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