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