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