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