Merge pull request #733 from amoiseev-softheme/bugfix/monofix
[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 // Copyright 2011 Xamarin Inc (http://www.xamarin.com).
10 //
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
18 // 
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
21 // 
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 //
30
31 using System.Security;
32 using System.Security.Policy;
33 using System.Security.Permissions;
34 using System.Runtime.Serialization;
35 using System.Reflection;
36 using System.IO;
37 using System.Globalization;
38 using System.Runtime.CompilerServices;
39 using System.Runtime.InteropServices;
40 using System.Collections.Generic;
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         [StructLayout (LayoutKind.Sequential)]
52 #if MOBILE
53         public partial class Assembly : ICustomAttributeProvider {
54 #elif NET_4_0
55         public abstract class Assembly : ICustomAttributeProvider, _Assembly, IEvidenceFactory, ISerializable {
56 #else
57         public partial class Assembly : ICustomAttributeProvider, _Assembly, IEvidenceFactory, ISerializable {
58 #endif
59                 internal class ResolveEventHolder {
60                         public event ModuleResolveEventHandler ModuleResolve;
61                 }
62
63                 // Note: changes to fields must be reflected in _MonoReflectionAssembly struct (object-internals.h)
64 #pragma warning disable 649
65                 private IntPtr _mono_assembly;
66 #pragma warning restore 649
67
68                 private ResolveEventHolder resolve_event_holder;
69 #if !MOBILE
70                 private Evidence _evidence;
71                 internal PermissionSet _minimum;        // for SecurityAction.RequestMinimum
72                 internal PermissionSet _optional;       // for SecurityAction.RequestOptional
73                 internal PermissionSet _refuse;         // for SecurityAction.RequestRefuse
74                 private PermissionSet _granted;         // for the resolved assembly granted permissions
75                 private PermissionSet _denied;          // for the resolved assembly denied permissions
76 #else
77                 object _evidence, _minimum, _optional, _refuse, _granted, _denied;
78 #endif
79                 private bool fromByteArray;
80                 private string assemblyName;
81
82 #if NET_4_0
83                 protected
84 #else
85                 internal
86 #endif
87                 Assembly () 
88                 {
89                         resolve_event_holder = new ResolveEventHolder ();
90                 }
91
92                 //
93                 // We can't store the event directly in this class, since the
94                 // compiler would silently insert the fields before _mono_assembly
95                 //
96                 public event ModuleResolveEventHandler ModuleResolve {
97                         [SecurityPermission (SecurityAction.LinkDemand, ControlAppDomain = true)]
98                         add {
99                                 resolve_event_holder.ModuleResolve += value;
100                         }
101                         [SecurityPermission (SecurityAction.LinkDemand, ControlAppDomain = true)]
102                         remove {
103                                 resolve_event_holder.ModuleResolve -= value;
104                         }
105                 }
106
107                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
108                 private extern string get_code_base (bool escaped);
109
110                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
111                 private extern string get_fullname ();
112
113                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
114                 private extern string get_location ();
115
116                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
117                 private extern string InternalImageRuntimeVersion ();
118
119                 // SECURITY: this should be the only caller to icall get_code_base
120                 private string GetCodeBase (bool escaped)
121                 {
122                         string cb = get_code_base (escaped);
123 #if !NET_2_1
124                         if (SecurityManager.SecurityEnabled) {
125                                 // we cannot divulge local file informations
126                                 if (String.Compare ("FILE://", 0, cb, 0, 7, true, CultureInfo.InvariantCulture) == 0) {
127                                         string file = cb.Substring (7);
128                                         new FileIOPermission (FileIOPermissionAccess.PathDiscovery, file).Demand ();
129                                 }
130                         }
131 #endif
132                         return cb;
133                 }
134
135                 public virtual string CodeBase {
136                         get { return GetCodeBase (false); }
137                 }
138
139                 public virtual string EscapedCodeBase {
140                         get { return GetCodeBase (true); }
141                 }
142
143                 public virtual string FullName {
144                         get {
145                                 //
146                                 // FIXME: This is wrong, but it gets us going
147                                 // in the compiler for now
148                                 //
149                                 return ToString ();
150                         }
151                 }
152
153                 public virtual extern MethodInfo EntryPoint {
154                         [MethodImplAttribute (MethodImplOptions.InternalCall)]
155                         get;
156                 }
157
158                 public virtual Evidence Evidence {
159                         [SecurityPermission (SecurityAction.Demand, ControlEvidence = true)]
160                         get { return UnprotectedGetEvidence (); }
161                 }
162
163                 // note: the security runtime requires evidences but may be unable to do so...
164                 internal Evidence UnprotectedGetEvidence ()
165                 {
166 #if MOBILE
167                         return null;
168 #else
169                         // if the host (runtime) hasn't provided it's own evidence...
170                         if (_evidence == null) {
171                                 // ... we will provide our own
172                                 lock (this) {
173                                         _evidence = Evidence.GetDefaultHostEvidence (this);
174                                 }
175                         }
176                         return _evidence;
177 #endif
178                 }
179
180                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
181                 internal extern bool get_global_assembly_cache ();
182
183                 internal bool FromByteArray {
184                         set { fromByteArray = value; }
185                 }
186
187                 public virtual String Location {
188                         get {
189                                 if (fromByteArray)
190                                         return String.Empty;
191
192                                 string loc = get_location ();
193 #if !NET_2_1
194                                 if ((loc != String.Empty) && SecurityManager.SecurityEnabled) {
195                                         // we cannot divulge local file informations
196                                         new FileIOPermission (FileIOPermissionAccess.PathDiscovery, loc).Demand ();
197                                 }
198 #endif
199                                 return loc;
200                         }
201                 }
202
203                 [ComVisible (false)]
204                 public virtual string ImageRuntimeVersion {
205                         get {
206                                 return InternalImageRuntimeVersion ();
207                         }
208                 }
209
210                 [SecurityPermission (SecurityAction.LinkDemand, SerializationFormatter = true)]
211                 public virtual void GetObjectData (SerializationInfo info, StreamingContext context)
212                 {
213                         if (info == null)
214                                 throw new ArgumentNullException ("info");
215
216                         UnitySerializationHolder.GetAssemblyData (this, info, context);
217                 }
218
219                 public virtual bool IsDefined (Type attributeType, bool inherit)
220                 {
221                         return MonoCustomAttrs.IsDefined (this, attributeType, inherit);
222                 }
223
224                 public virtual object [] GetCustomAttributes (bool inherit)
225                 {
226                         return MonoCustomAttrs.GetCustomAttributes (this, inherit);
227                 }
228
229                 public virtual object [] GetCustomAttributes (Type attributeType, bool inherit)
230                 {
231                         return MonoCustomAttrs.GetCustomAttributes (this, attributeType, inherit);
232                 }
233
234                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
235                 private extern object GetFilesInternal (String name, bool getResourceModules);
236
237                 public virtual FileStream[] GetFiles ()
238                 {
239                         return GetFiles (false);
240                 }
241
242                 public virtual FileStream [] GetFiles (bool getResourceModules)
243                 {
244                         string[] names = (string[]) GetFilesInternal (null, getResourceModules);
245                         if (names == null)
246                                 return EmptyArray<FileStream>.Value;
247
248                         string location = Location;
249
250                         FileStream[] res;
251                         if (location != String.Empty) {
252                                 res = new FileStream [names.Length + 1];
253                                 res [0] = new FileStream (location, FileMode.Open, FileAccess.Read);
254                                 for (int i = 0; i < names.Length; ++i)
255                                         res [i + 1] = new FileStream (names [i], FileMode.Open, FileAccess.Read);
256                         } else {
257                                 res = new FileStream [names.Length];
258                                 for (int i = 0; i < names.Length; ++i)
259                                         res [i] = new FileStream (names [i], FileMode.Open, FileAccess.Read);
260                         }
261                         return res;
262                 }
263
264                 public virtual FileStream GetFile (String name)
265                 {
266                         if (name == null)
267                                 throw new ArgumentNullException (null, "Name cannot be null.");
268                         if (name.Length == 0)
269                                 throw new ArgumentException ("Empty name is not valid");
270
271                         string filename = (string)GetFilesInternal (name, true);
272                         if (filename != null)
273                                 return new FileStream (filename, FileMode.Open, FileAccess.Read);
274                         else
275                                 return null;
276                 }
277
278                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
279                 internal extern IntPtr GetManifestResourceInternal (String name, out int size, out Module module);
280
281                 public virtual Stream GetManifestResourceStream (String name)
282                 {
283                         if (name == null)
284                                 throw new ArgumentNullException ("name");
285                         if (name.Length == 0)
286                                 throw new ArgumentException ("String cannot have zero length.",
287                                         "name");
288
289                         ManifestResourceInfo info = GetManifestResourceInfo (name);
290                         if (info == null) {
291                                 Assembly a = AppDomain.CurrentDomain.DoResourceResolve (name, this);
292                                 if (a != null && a != this)
293                                         return a.GetManifestResourceStream (name);
294                                 else
295                                         return null;
296                         }
297
298                         if (info.ReferencedAssembly != null)
299                                 return info.ReferencedAssembly.GetManifestResourceStream (name);
300                         if ((info.FileName != null) && (info.ResourceLocation == 0)) {
301                                 if (fromByteArray)
302                                         throw new FileNotFoundException (info.FileName);
303
304                                 string location = Path.GetDirectoryName (Location);
305                                 string filename = Path.Combine (location, info.FileName);
306                                 return new FileStream (filename, FileMode.Open, FileAccess.Read);
307                         }
308
309                         int size;
310                         Module module;
311                         IntPtr data = GetManifestResourceInternal (name, out size, out module);
312                         if (data == (IntPtr) 0)
313                                 return null;
314                         else {
315                                 UnmanagedMemoryStream stream;
316                                 unsafe {
317                                         stream = new UnmanagedMemoryStream ((byte*) data, size);
318                                 }
319                                 /* 
320                                  * The returned pointer points inside metadata, so
321                                  * we have to increase the refcount of the module, and decrease
322                                  * it when the stream is finalized.
323                                  */
324                                 stream.Closed += new EventHandler (new ResourceCloseHandler (module).OnClose);
325                                 return stream;
326                         }
327                 }
328
329                 public virtual Stream GetManifestResourceStream (Type type, String name)
330                 {
331                         string ns;
332                         if (type != null) {
333                                 ns = type.Namespace;
334                         } else {
335                                 if (name == null)
336                                         throw new ArgumentNullException ("type");
337                                 ns = null;
338                         }
339
340                         if (ns == null || ns.Length == 0)
341                                 return GetManifestResourceStream (name);
342                         else
343                                 return GetManifestResourceStream (ns + "." + name);
344                 }
345
346                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
347                 internal virtual extern Type[] GetTypes (bool exportedOnly);
348                 
349                 public virtual Type[] GetTypes ()
350                 {
351                         return GetTypes (false);
352                 }
353
354                 public virtual Type[] GetExportedTypes ()
355                 {
356                         return GetTypes (true);
357                 }
358
359                 public virtual Type GetType (String name, Boolean throwOnError)
360                 {
361                         return GetType (name, throwOnError, false);
362                 }
363
364                 public virtual Type GetType (String name) {
365                         return GetType (name, false, false);
366                 }
367
368                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
369                 internal extern Type InternalGetType (Module module, String name, Boolean throwOnError, Boolean ignoreCase);
370
371                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
372                 internal extern static void InternalGetAssemblyName (string assemblyFile, AssemblyName aname);
373
374                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
375                 static extern void FillName (Assembly ass, AssemblyName aname);
376
377                 [MonoTODO ("copiedName == true is not supported")]
378                 public virtual AssemblyName GetName (Boolean copiedName)
379                 {
380 #if !MOBILE
381                         // CodeBase, which is restricted, will be copied into the AssemblyName object so...
382                         if (SecurityManager.SecurityEnabled) {
383                                 GetCodeBase (true); // this will ensure the Demand is made
384                         }
385 #endif
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                 internal Assembly GetSatelliteAssemblyNoThrow (CultureInfo culture, Version version)
430                 {
431                         return GetSatelliteAssembly (culture, version, false);
432                 }
433
434                 internal Assembly GetSatelliteAssembly (CultureInfo culture, Version version, bool throwOnError)
435                 {
436                         if (culture == null)
437                                 throw new ArgumentException ("culture");
438
439                         AssemblyName aname = GetName (true);
440                         if (version != null)
441                                 aname.Version = version;
442
443                         aname.CultureInfo = culture;
444                         aname.Name = aname.Name + ".resources";
445                         Assembly assembly;
446
447                         try {
448                                 assembly = AppDomain.CurrentDomain.LoadSatellite (aname, false);
449                                 if (assembly != null)
450                                         return assembly;
451                         } catch (FileNotFoundException) {
452                                 assembly = null;
453                                 // ignore
454                         }
455
456                         // Try the assembly directory
457                         string location = Path.GetDirectoryName (Location);
458                         string fullName = Path.Combine (location, Path.Combine (culture.Name, aname.Name + ".dll"));
459                         if (!throwOnError && !File.Exists (fullName))
460                                 return null;
461
462                         return LoadFrom (fullName);
463                 }
464
465 #if !MOBILE
466                 Type _Assembly.GetType ()
467                 {
468                         // Required or object::GetType becomes virtual final
469                         return base.GetType ();
470                 }               
471 #endif
472
473                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
474                 private extern static Assembly LoadFrom (String assemblyFile, bool refonly);
475
476                 public static Assembly LoadFrom (String assemblyFile)
477                 {
478                         return LoadFrom (assemblyFile, false);
479                 }
480
481 #if NET_4_0
482                 [Obsolete]
483 #endif
484                 public static Assembly LoadFrom (String assemblyFile, Evidence securityEvidence)
485                 {
486                         Assembly a = LoadFrom (assemblyFile, false);
487 #if !NET_2_1
488                         if ((a != null) && (securityEvidence != null)) {
489                                 // merge evidence (i.e. replace defaults with provided evidences)
490                                 a.Evidence.Merge (securityEvidence);
491                         }
492 #endif
493                         return a;
494                 }
495
496 #if NET_4_0
497                 [Obsolete]
498 #endif
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                         throw new NotImplementedException ();
504                 }
505
506 #if NET_4_0
507                 [MonoTODO]
508                 public static Assembly LoadFrom (String assemblyFile, byte [] hashValue, AssemblyHashAlgorithm hashAlgorithm)
509                 {
510                         throw new NotImplementedException ();
511                 }
512 #endif
513
514 #if NET_4_0
515                 public static Assembly UnsafeLoadFrom (String assemblyFile)
516                 {
517                         return LoadFrom (assemblyFile);
518                 }
519 #endif
520
521 #if NET_4_0
522                 [Obsolete]
523 #endif
524                 public static Assembly LoadFile (String path, Evidence securityEvidence)
525                 {
526                         if (path == null)
527                                 throw new ArgumentNullException ("path");
528                         if (path == String.Empty)
529                                 throw new ArgumentException ("Path can't be empty", "path");
530                         // FIXME: Make this do the right thing
531                         return LoadFrom (path, securityEvidence);
532                 }
533
534                 public static Assembly LoadFile (String path)
535                 {
536                         return LoadFile (path, null);
537                 }
538
539                 public static Assembly Load (String assemblyString)
540                 {
541                         return AppDomain.CurrentDomain.Load (assemblyString);
542                 }
543
544 #if NET_4_0
545                 [Obsolete]
546 #endif          
547                 public static Assembly Load (String assemblyString, Evidence assemblySecurity)
548                 {
549                         return AppDomain.CurrentDomain.Load (assemblyString, assemblySecurity);
550                 }
551
552                 public static Assembly Load (AssemblyName assemblyRef)
553                 {
554                         return AppDomain.CurrentDomain.Load (assemblyRef);
555                 }
556
557 #if NET_4_0
558                 [Obsolete]
559 #endif
560                 public static Assembly Load (AssemblyName assemblyRef, Evidence assemblySecurity)
561                 {
562                         return AppDomain.CurrentDomain.Load (assemblyRef, assemblySecurity);
563                 }
564
565                 public static Assembly Load (Byte[] rawAssembly)
566                 {
567                         return AppDomain.CurrentDomain.Load (rawAssembly);
568                 }
569
570                 public static Assembly Load (Byte[] rawAssembly, Byte[] rawSymbolStore)
571                 {
572                         return AppDomain.CurrentDomain.Load (rawAssembly, rawSymbolStore);
573                 }
574
575 #if NET_4_0
576                 [Obsolete]
577 #endif
578                 public static Assembly Load (Byte[] rawAssembly, Byte[] rawSymbolStore,
579                                              Evidence securityEvidence)
580                 {
581                         return AppDomain.CurrentDomain.Load (rawAssembly, rawSymbolStore, securityEvidence);
582                 }
583
584 #if NET_4_0
585                 [MonoLimitation ("Argument securityContextSource is ignored")]
586                 public static Assembly Load (byte [] rawAssembly, byte [] rawSymbolStore, SecurityContextSource securityContextSource)
587                 {
588                         return AppDomain.CurrentDomain.Load (rawAssembly, rawSymbolStore);
589                 }
590 #endif
591
592                 public static Assembly ReflectionOnlyLoad (byte[] rawAssembly)
593                 {
594                         return AppDomain.CurrentDomain.Load (rawAssembly, null, null, true);
595                 }
596
597                 public static Assembly ReflectionOnlyLoad (string assemblyString) 
598                 {
599                         return AppDomain.CurrentDomain.Load (assemblyString, null, true);
600                 }
601
602                 public static Assembly ReflectionOnlyLoadFrom (string assemblyFile) 
603                 {
604                         if (assemblyFile == null)
605                                 throw new ArgumentNullException ("assemblyFile");
606                         
607                         return LoadFrom (assemblyFile, true);
608                 }
609
610                 [Obsolete]
611                 public static Assembly LoadWithPartialName (string partialName)
612                 {
613                         return LoadWithPartialName (partialName, null);
614                 }
615
616                 [MonoTODO ("Not implemented")]
617                 public Module LoadModule (string moduleName, byte [] rawModule)
618                 {
619                         throw new NotImplementedException ();
620                 }
621
622                 [MonoTODO ("Not implemented")]
623                 public
624 #if NET_4_0
625                 virtual
626 #endif
627                 Module LoadModule (string moduleName, byte [] rawModule, byte [] rawSymbolStore)
628                 {
629                         throw new NotImplementedException ();
630                 }
631
632                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
633                 private static extern Assembly load_with_partial_name (string name, Evidence e);
634
635                 [Obsolete]
636                 public static Assembly LoadWithPartialName (string partialName, Evidence securityEvidence)
637                 {
638                         return LoadWithPartialName (partialName, securityEvidence, true);
639                 }
640
641                 /**
642                  * LAMESPEC: It is possible for this method to throw exceptions IF the name supplied
643                  * is a valid gac name and contains filesystem entry charachters at the end of the name
644                  * ie System/// will throw an exception. However ////System will not as that is canocolized
645                  * out of the name.
646                  */
647
648                 // FIXME: LoadWithPartialName must look cache (no CAS) or read from disk (CAS)
649                 internal static Assembly LoadWithPartialName (string partialName, Evidence securityEvidence, bool oldBehavior)
650                 {
651                         if (!oldBehavior)
652                                 throw new NotImplementedException ();
653
654                         if (partialName == null)
655                                 throw new NullReferenceException ();
656
657                         return load_with_partial_name (partialName, securityEvidence);
658                 }
659
660                 public Object CreateInstance (String typeName) 
661                 {
662                         return CreateInstance (typeName, false);
663                 }
664
665                 public Object CreateInstance (String typeName, Boolean ignoreCase)
666                 {
667                         Type t = GetType (typeName, false, ignoreCase);
668                         if (t == null)
669                                 return null;
670
671                         try {
672                                 return Activator.CreateInstance (t);
673                         } catch (InvalidOperationException) {
674                                 throw new ArgumentException ("It is illegal to invoke a method on a Type loaded via ReflectionOnly methods.");
675                         }
676                 }
677
678                 public
679 #if NET_4_0
680                 virtual
681 #endif
682                 Object CreateInstance (String typeName, Boolean ignoreCase,
683                                               BindingFlags bindingAttr, Binder binder,
684                                               Object[] args, CultureInfo culture,
685                                               Object[] activationAttributes)
686                 {
687                         Type t = GetType (typeName, false, ignoreCase);
688                         if (t == null)
689                                 return null;
690
691                         try {
692                                 return Activator.CreateInstance (t, bindingAttr, binder, args, culture, activationAttributes);
693                         } catch (InvalidOperationException) {
694                                 throw new ArgumentException ("It is illegal to invoke a method on a Type loaded via ReflectionOnly methods.");
695                         }
696                 }
697
698                 public Module[] GetLoadedModules ()
699                 {
700                         return GetLoadedModules (false);
701                 }
702
703                 public Module[] GetModules ()
704                 {
705                         return GetModules (false);
706                 }
707
708                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
709                 internal virtual extern Module[] GetModulesInternal ();
710                 
711                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
712                 public extern virtual String[] GetManifestResourceNames ();
713
714                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
715                 public extern static Assembly GetExecutingAssembly ();
716
717                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
718                 public extern static Assembly GetCallingAssembly ();
719
720                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
721                 internal static extern AssemblyName[] GetReferencedAssemblies (Assembly module);
722
723                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
724                 private extern bool GetManifestResourceInfoInternal (String name, ManifestResourceInfo info);
725
726                 public virtual ManifestResourceInfo GetManifestResourceInfo (String resourceName)
727                 {
728                         if (resourceName == null)
729                                 throw new ArgumentNullException ("resourceName");
730                         if (resourceName.Length == 0)
731                                 throw new ArgumentException ("String cannot have zero length.");
732                         ManifestResourceInfo result = new ManifestResourceInfo ();
733                         bool found = GetManifestResourceInfoInternal (resourceName, result);
734                         if (found)
735                                 return result;
736                         else
737                                 return null;
738                 }
739
740                 private class ResourceCloseHandler {
741 #pragma warning disable 169, 414
742                         Module module;
743 #pragma warning restore 169, 414                        
744
745                         public ResourceCloseHandler (Module module) {
746                                 this.module = module;
747                         }
748
749                         public void OnClose (object sender, EventArgs e) {
750                                 // The module dtor will take care of things
751                                 module = null;
752                         }
753                 }
754
755                 //
756                 // The following functions are only for the Mono Debugger.
757                 //
758
759                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
760                 internal static extern int MonoDebugger_GetMethodToken (MethodBase method);
761
762                 [MonoTODO ("Currently it always returns zero")]
763                 [ComVisible (false)]
764                 public
765 #if NET_4_0
766                 virtual
767 #endif
768                 long HostContext {
769                         get { return 0; }
770                 }
771
772
773                 internal virtual Module GetManifestModule () {
774                         return GetManifestModuleInternal ();
775                 }
776
777                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
778                 internal extern Module GetManifestModuleInternal ();
779
780                 [ComVisible (false)]
781                 public virtual extern bool ReflectionOnly {
782                         [MethodImplAttribute (MethodImplOptions.InternalCall)]
783                         get;
784                 }
785                 
786                 public override int GetHashCode ()
787                 {
788                         return base.GetHashCode ();
789                 }
790
791                 public override bool Equals (object o)
792                 {
793                         if (((object) this) == o)
794                                 return true;
795
796                         if (o == null)
797                                 return false;
798                         
799                         Assembly other = (Assembly) o;
800                         return other._mono_assembly == _mono_assembly;
801                 }
802
803 #if !NET_2_1
804                 // Code Access Security
805
806                 internal void Resolve () 
807                 {
808                         lock (this) {
809                                 // FIXME: As we (currently) delay the resolution until the first CAS
810                                 // Demand it's too late to evaluate the Minimum permission set as a 
811                                 // condition to load the assembly into the AppDomain
812                                 LoadAssemblyPermissions ();
813                                 Evidence e = new Evidence (UnprotectedGetEvidence ()); // we need a copy to add PRE
814                                 e.AddHost (new PermissionRequestEvidence (_minimum, _optional, _refuse));
815                                 _granted = SecurityManager.ResolvePolicy (e,
816                                         _minimum, _optional, _refuse, out _denied);
817                         }
818                 }
819
820                 internal PermissionSet GrantedPermissionSet {
821                         get {
822                                 if (_granted == null) {
823                                         if (SecurityManager.ResolvingPolicyLevel != null) {
824                                                 if (SecurityManager.ResolvingPolicyLevel.IsFullTrustAssembly (this))
825                                                         return DefaultPolicies.FullTrust;
826                                                 else
827                                                         return null; // we can't resolve during resolution
828                                         }
829                                         Resolve ();
830                                 }
831                                 return _granted;
832                         }
833                 }
834
835                 internal PermissionSet DeniedPermissionSet {
836                         get {
837                                 // yes we look for granted, as denied may be null
838                                 if (_granted == null) {
839                                         if (SecurityManager.ResolvingPolicyLevel != null) {
840                                                 if (SecurityManager.ResolvingPolicyLevel.IsFullTrustAssembly (this))
841                                                         return null;
842                                                 else
843                                                         return DefaultPolicies.FullTrust; // deny unrestricted
844                                         }
845                                         Resolve ();
846                                 }
847                                 return _denied;
848                         }
849                 }
850
851                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
852                 extern internal static bool LoadPermissions (Assembly a, 
853                         ref IntPtr minimum, ref int minLength,
854                         ref IntPtr optional, ref int optLength,
855                         ref IntPtr refused, ref int refLength);
856
857                 // Support for SecurityAction.RequestMinimum, RequestOptional and RequestRefuse
858                 private void LoadAssemblyPermissions ()
859                 {
860                         IntPtr minimum = IntPtr.Zero, optional = IntPtr.Zero, refused = IntPtr.Zero;
861                         int minLength = 0, optLength = 0, refLength = 0;
862                         if (LoadPermissions (this, ref minimum, ref minLength, ref optional,
863                                 ref optLength, ref refused, ref refLength)) {
864
865                                 // Note: no need to cache these permission sets as they will only be created once
866                                 // at assembly resolution time.
867                                 if (minLength > 0) {
868                                         byte[] data = new byte [minLength];
869                                         Marshal.Copy (minimum, data, 0, minLength);
870                                         _minimum = SecurityManager.Decode (data);
871                                 }
872                                 if (optLength > 0) {
873                                         byte[] data = new byte [optLength];
874                                         Marshal.Copy (optional, data, 0, optLength);
875                                         _optional = SecurityManager.Decode (data);
876                                 }
877                                 if (refLength > 0) {
878                                         byte[] data = new byte [refLength];
879                                         Marshal.Copy (refused, data, 0, refLength);
880                                         _refuse = SecurityManager.Decode (data);
881                                 }
882                         }
883                 }
884                 
885 #if NET_4_0
886                 public virtual PermissionSet PermissionSet {
887                         get { return this.GrantedPermissionSet; }
888                 }
889                 
890                 public virtual SecurityRuleSet SecurityRuleSet {
891                         get { throw CreateNIE (); }
892                 }
893 #endif
894
895 #endif
896
897 #if NET_4_0
898                 static Exception CreateNIE ()
899                 {
900                         return new NotImplementedException ("Derived classes must implement it");
901                 }
902                 
903                 public virtual IList<CustomAttributeData> GetCustomAttributesData ()
904                 {
905                         return CustomAttributeData.GetCustomAttributes (this);
906                 }
907
908                 [MonoTODO]
909                 public bool IsFullyTrusted {
910                         get { return true; }
911                 }
912
913                 public virtual Type GetType (string name, bool throwOnError, bool ignoreCase)
914                 {
915                         throw CreateNIE ();
916                 }
917
918                 public virtual Module GetModule (String name)
919                 {
920                         throw CreateNIE ();
921                 }
922
923                 public virtual AssemblyName[] GetReferencedAssemblies ()
924                 {
925                         throw CreateNIE ();
926                 }
927
928                 public virtual Module[] GetModules (bool getResourceModules)
929                 {
930                         throw CreateNIE ();
931                 }
932
933                 [MonoTODO ("Always returns the same as GetModules")]
934                 public virtual Module[] GetLoadedModules (bool getResourceModules)
935                 {
936                         throw CreateNIE ();
937                 }
938
939                 public virtual Assembly GetSatelliteAssembly (CultureInfo culture)
940                 {
941                         throw CreateNIE ();
942                 }
943
944                 public virtual Assembly GetSatelliteAssembly (CultureInfo culture, Version version)
945                 {
946                         throw CreateNIE ();
947                 }
948
949                 public virtual Module ManifestModule {
950                         get { throw CreateNIE (); }
951                 }
952
953                 public virtual bool GlobalAssemblyCache {
954                         get { throw CreateNIE (); }
955                 }
956
957                 public virtual bool IsDynamic {
958                         get { return false; }
959                 }
960
961                 public static bool operator == (Assembly left, Assembly right)
962                 {
963                         if ((object)left == (object)right)
964                                 return true;
965                         if ((object)left == null ^ (object)right == null)
966                                 return false;
967                         return left.Equals (right);
968                 }
969
970                 public static bool operator != (Assembly left, Assembly right)
971                 {
972                         if ((object)left == (object)right)
973                                 return false;
974                         if ((object)left == null ^ (object)right == null)
975                                 return true;
976                         return !left.Equals (right);
977                 }
978 #endif
979
980 #if NET_4_5
981                 public virtual IEnumerable<TypeInfo> DefinedTypes {
982                         get {
983                                 foreach (var type in GetTypes ())
984                                         yield return new TypeDelegator (type);
985                         }
986                 }
987
988                 public virtual IEnumerable<Type> ExportedTypes {
989                         get { return GetExportedTypes (); }
990                 }
991
992                 public virtual IEnumerable<Module> Modules {
993                         get { return GetModules (); }
994                 }
995
996                 public virtual IEnumerable<CustomAttributeData> CustomAttributes {
997                         get { return GetCustomAttributesData (); }
998                 }
999 #endif
1000         }
1001 }