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