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