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