Merge pull request #537 from madewokherd/ccwmarshal
[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 NET_4_0
55         public abstract class Assembly : ICustomAttributeProvider, _Assembly, IEvidenceFactory, ISerializable {
56 #else
57         public partial class Assembly : ICustomAttributeProvider, _Assembly, IEvidenceFactory, ISerializable {
58 #endif
59                 internal class ResolveEventHolder {
60                         public event ModuleResolveEventHandler ModuleResolve;
61                 }
62
63                 // Note: changes to fields must be reflected in _MonoReflectionAssembly struct (object-internals.h)
64 #pragma warning disable 649
65                 private IntPtr _mono_assembly;
66 #pragma warning restore 649
67
68                 private ResolveEventHolder resolve_event_holder;
69 #if !MOBILE
70                 private Evidence _evidence;
71                 internal PermissionSet _minimum;        // for SecurityAction.RequestMinimum
72                 internal PermissionSet _optional;       // for SecurityAction.RequestOptional
73                 internal PermissionSet _refuse;         // for SecurityAction.RequestRefuse
74                 private PermissionSet _granted;         // for the resolved assembly granted permissions
75                 private PermissionSet _denied;          // for the resolved assembly denied permissions
76 #endif
77                 private bool fromByteArray;
78                 private string assemblyName;
79
80 #if NET_4_0
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
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                 internal bool FromByteArray {
182                         set { fromByteArray = value; }
183                 }
184
185                 public virtual String Location {
186                         get {
187                                 if (fromByteArray)
188                                         return String.Empty;
189
190                                 string loc = get_location ();
191 #if !NET_2_1
192                                 if ((loc != String.Empty) && SecurityManager.SecurityEnabled) {
193                                         // we cannot divulge local file informations
194                                         new FileIOPermission (FileIOPermissionAccess.PathDiscovery, loc).Demand ();
195                                 }
196 #endif
197                                 return loc;
198                         }
199                 }
200
201                 [ComVisible (false)]
202                 public virtual string ImageRuntimeVersion {
203                         get {
204                                 return InternalImageRuntimeVersion ();
205                         }
206                 }
207
208                 [SecurityPermission (SecurityAction.LinkDemand, SerializationFormatter = true)]
209                 public virtual void GetObjectData (SerializationInfo info, StreamingContext context)
210                 {
211                         if (info == null)
212                                 throw new ArgumentNullException ("info");
213
214                         UnitySerializationHolder.GetAssemblyData (this, info, context);
215                 }
216
217                 public virtual bool IsDefined (Type attributeType, bool inherit)
218                 {
219                         return MonoCustomAttrs.IsDefined (this, attributeType, inherit);
220                 }
221
222                 public virtual object [] GetCustomAttributes (bool inherit)
223                 {
224                         return MonoCustomAttrs.GetCustomAttributes (this, inherit);
225                 }
226
227                 public virtual object [] GetCustomAttributes (Type attributeType, bool inherit)
228                 {
229                         return MonoCustomAttrs.GetCustomAttributes (this, attributeType, inherit);
230                 }
231
232                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
233                 private extern object GetFilesInternal (String name, bool getResourceModules);
234
235                 public virtual FileStream[] GetFiles ()
236                 {
237                         return GetFiles (false);
238                 }
239
240                 public virtual FileStream [] GetFiles (bool getResourceModules)
241                 {
242                         string[] names = (string[]) GetFilesInternal (null, getResourceModules);
243                         if (names == null)
244                                 return EmptyArray<FileStream>.Value;
245
246                         string location = Location;
247
248                         FileStream[] res;
249                         if (location != String.Empty) {
250                                 res = new FileStream [names.Length + 1];
251                                 res [0] = new FileStream (location, FileMode.Open, FileAccess.Read);
252                                 for (int i = 0; i < names.Length; ++i)
253                                         res [i + 1] = new FileStream (names [i], FileMode.Open, FileAccess.Read);
254                         } else {
255                                 res = new FileStream [names.Length];
256                                 for (int i = 0; i < names.Length; ++i)
257                                         res [i] = new FileStream (names [i], FileMode.Open, FileAccess.Read);
258                         }
259                         return res;
260                 }
261
262                 public virtual FileStream GetFile (String name)
263                 {
264                         if (name == null)
265                                 throw new ArgumentNullException (null, "Name cannot be null.");
266                         if (name.Length == 0)
267                                 throw new ArgumentException ("Empty name is not valid");
268
269                         string filename = (string)GetFilesInternal (name, true);
270                         if (filename != null)
271                                 return new FileStream (filename, FileMode.Open, FileAccess.Read);
272                         else
273                                 return null;
274                 }
275
276                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
277                 internal extern IntPtr GetManifestResourceInternal (String name, out int size, out Module module);
278
279                 public virtual Stream GetManifestResourceStream (String name)
280                 {
281                         if (name == null)
282                                 throw new ArgumentNullException ("name");
283                         if (name.Length == 0)
284                                 throw new ArgumentException ("String cannot have zero length.",
285                                         "name");
286
287                         ManifestResourceInfo info = GetManifestResourceInfo (name);
288                         if (info == null) {
289                                 Assembly a = AppDomain.CurrentDomain.DoResourceResolve (name, this);
290                                 if (a != null && a != this)
291                                         return a.GetManifestResourceStream (name);
292                                 else
293                                         return null;
294                         }
295
296                         if (info.ReferencedAssembly != null)
297                                 return info.ReferencedAssembly.GetManifestResourceStream (name);
298                         if ((info.FileName != null) && (info.ResourceLocation == 0)) {
299                                 if (fromByteArray)
300                                         throw new FileNotFoundException (info.FileName);
301
302                                 string location = Path.GetDirectoryName (Location);
303                                 string filename = Path.Combine (location, info.FileName);
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 (!throwOnError && !File.Exists (fullName))
456                                 return null;
457
458                         return LoadFrom (fullName);
459                 }
460
461                 Type _Assembly.GetType ()
462                 {
463                         // Required or object::GetType becomes virtual final
464                         return base.GetType ();
465                 }               
466                 
467                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
468                 private extern static Assembly LoadFrom (String assemblyFile, bool refonly);
469
470                 public static Assembly LoadFrom (String assemblyFile)
471                 {
472                         return LoadFrom (assemblyFile, false);
473                 }
474
475 #if NET_4_0
476                 [Obsolete]
477 #endif
478                 public static Assembly LoadFrom (String assemblyFile, Evidence securityEvidence)
479                 {
480                         Assembly a = LoadFrom (assemblyFile, false);
481 #if !NET_2_1
482                         if ((a != null) && (securityEvidence != null)) {
483                                 // merge evidence (i.e. replace defaults with provided evidences)
484                                 a.Evidence.Merge (securityEvidence);
485                         }
486 #endif
487                         return a;
488                 }
489
490 #if NET_4_0
491                 [Obsolete]
492 #endif
493                 [MonoTODO("This overload is not currently implemented")]
494                 // FIXME: What are we missing?
495                 public static Assembly LoadFrom (String assemblyFile, Evidence securityEvidence, byte[] hashValue, AssemblyHashAlgorithm hashAlgorithm)
496                 {
497                         throw new NotImplementedException ();
498                 }
499
500 #if NET_4_0
501                 [MonoTODO]
502                 public static Assembly LoadFrom (String assemblyFile, byte [] hashValue, AssemblyHashAlgorithm hashAlgorithm)
503                 {
504                         throw new NotImplementedException ();
505                 }
506 #endif
507
508 #if NET_4_0
509                 public static Assembly UnsafeLoadFrom (String assemblyFile)
510                 {
511                         return LoadFrom (assemblyFile);
512                 }
513 #endif
514
515 #if NET_4_0
516                 [Obsolete]
517 #endif
518                 public static Assembly LoadFile (String path, Evidence securityEvidence)
519                 {
520                         if (path == null)
521                                 throw new ArgumentNullException ("path");
522                         if (path == String.Empty)
523                                 throw new ArgumentException ("Path can't be empty", "path");
524                         // FIXME: Make this do the right thing
525                         return LoadFrom (path, securityEvidence);
526                 }
527
528                 public static Assembly LoadFile (String path)
529                 {
530                         return LoadFile (path, null);
531                 }
532
533                 public static Assembly Load (String assemblyString)
534                 {
535                         return AppDomain.CurrentDomain.Load (assemblyString);
536                 }
537
538 #if NET_4_0
539                 [Obsolete]
540 #endif          
541                 public static Assembly Load (String assemblyString, Evidence assemblySecurity)
542                 {
543                         return AppDomain.CurrentDomain.Load (assemblyString, assemblySecurity);
544                 }
545
546                 public static Assembly Load (AssemblyName assemblyRef)
547                 {
548                         return AppDomain.CurrentDomain.Load (assemblyRef);
549                 }
550
551 #if NET_4_0
552                 [Obsolete]
553 #endif
554                 public static Assembly Load (AssemblyName assemblyRef, Evidence assemblySecurity)
555                 {
556                         return AppDomain.CurrentDomain.Load (assemblyRef, assemblySecurity);
557                 }
558
559                 public static Assembly Load (Byte[] rawAssembly)
560                 {
561                         return AppDomain.CurrentDomain.Load (rawAssembly);
562                 }
563
564                 public static Assembly Load (Byte[] rawAssembly, Byte[] rawSymbolStore)
565                 {
566                         return AppDomain.CurrentDomain.Load (rawAssembly, rawSymbolStore);
567                 }
568
569 #if NET_4_0
570                 [Obsolete]
571 #endif
572                 public static Assembly Load (Byte[] rawAssembly, Byte[] rawSymbolStore,
573                                              Evidence securityEvidence)
574                 {
575                         return AppDomain.CurrentDomain.Load (rawAssembly, rawSymbolStore, securityEvidence);
576                 }
577
578 #if NET_4_0
579                 [MonoLimitation ("Argument securityContextSource is ignored")]
580                 public static Assembly Load (byte [] rawAssembly, byte [] rawSymbolStore, SecurityContextSource securityContextSource)
581                 {
582                         return AppDomain.CurrentDomain.Load (rawAssembly, rawSymbolStore);
583                 }
584 #endif
585
586                 public static Assembly ReflectionOnlyLoad (byte[] rawAssembly)
587                 {
588                         return AppDomain.CurrentDomain.Load (rawAssembly, null, null, true);
589                 }
590
591                 public static Assembly ReflectionOnlyLoad (string assemblyString) 
592                 {
593                         return AppDomain.CurrentDomain.Load (assemblyString, null, true);
594                 }
595
596                 public static Assembly ReflectionOnlyLoadFrom (string assemblyFile) 
597                 {
598                         if (assemblyFile == null)
599                                 throw new ArgumentNullException ("assemblyFile");
600                         
601                         return LoadFrom (assemblyFile, true);
602                 }
603
604                 [Obsolete]
605                 public static Assembly LoadWithPartialName (string partialName)
606                 {
607                         return LoadWithPartialName (partialName, null);
608                 }
609
610                 [MonoTODO ("Not implemented")]
611                 public Module LoadModule (string moduleName, byte [] rawModule)
612                 {
613                         throw new NotImplementedException ();
614                 }
615
616                 [MonoTODO ("Not implemented")]
617                 public
618 #if NET_4_0
619                 virtual
620 #endif
621                 Module LoadModule (string moduleName, byte [] rawModule, byte [] rawSymbolStore)
622                 {
623                         throw new NotImplementedException ();
624                 }
625
626                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
627                 private static extern Assembly load_with_partial_name (string name, Evidence e);
628
629                 [Obsolete]
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
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
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 int GetHashCode ()
785                 {
786                         return base.GetHashCode ();
787                 }
788
789                 public override bool Equals (object o)
790                 {
791                         if (((object) this) == o)
792                                 return true;
793
794                         if (o == null)
795                                 return false;
796                         
797                         Assembly other = (Assembly) o;
798                         return other._mono_assembly == _mono_assembly;
799                 }
800
801 #if !NET_2_1
802                 // Code Access Security
803
804                 internal void Resolve () 
805                 {
806                         lock (this) {
807                                 // FIXME: As we (currently) delay the resolution until the first CAS
808                                 // Demand it's too late to evaluate the Minimum permission set as a 
809                                 // condition to load the assembly into the AppDomain
810                                 LoadAssemblyPermissions ();
811                                 Evidence e = new Evidence (UnprotectedGetEvidence ()); // we need a copy to add PRE
812                                 e.AddHost (new PermissionRequestEvidence (_minimum, _optional, _refuse));
813                                 _granted = SecurityManager.ResolvePolicy (e,
814                                         _minimum, _optional, _refuse, out _denied);
815                         }
816                 }
817
818                 internal PermissionSet GrantedPermissionSet {
819                         get {
820                                 if (_granted == null) {
821                                         if (SecurityManager.ResolvingPolicyLevel != null) {
822                                                 if (SecurityManager.ResolvingPolicyLevel.IsFullTrustAssembly (this))
823                                                         return DefaultPolicies.FullTrust;
824                                                 else
825                                                         return null; // we can't resolve during resolution
826                                         }
827                                         Resolve ();
828                                 }
829                                 return _granted;
830                         }
831                 }
832
833                 internal PermissionSet DeniedPermissionSet {
834                         get {
835                                 // yes we look for granted, as denied may be null
836                                 if (_granted == null) {
837                                         if (SecurityManager.ResolvingPolicyLevel != null) {
838                                                 if (SecurityManager.ResolvingPolicyLevel.IsFullTrustAssembly (this))
839                                                         return null;
840                                                 else
841                                                         return DefaultPolicies.FullTrust; // deny unrestricted
842                                         }
843                                         Resolve ();
844                                 }
845                                 return _denied;
846                         }
847                 }
848
849                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
850                 extern internal static bool LoadPermissions (Assembly a, 
851                         ref IntPtr minimum, ref int minLength,
852                         ref IntPtr optional, ref int optLength,
853                         ref IntPtr refused, ref int refLength);
854
855                 // Support for SecurityAction.RequestMinimum, RequestOptional and RequestRefuse
856                 private void LoadAssemblyPermissions ()
857                 {
858                         IntPtr minimum = IntPtr.Zero, optional = IntPtr.Zero, refused = IntPtr.Zero;
859                         int minLength = 0, optLength = 0, refLength = 0;
860                         if (LoadPermissions (this, ref minimum, ref minLength, ref optional,
861                                 ref optLength, ref refused, ref refLength)) {
862
863                                 // Note: no need to cache these permission sets as they will only be created once
864                                 // at assembly resolution time.
865                                 if (minLength > 0) {
866                                         byte[] data = new byte [minLength];
867                                         Marshal.Copy (minimum, data, 0, minLength);
868                                         _minimum = SecurityManager.Decode (data);
869                                 }
870                                 if (optLength > 0) {
871                                         byte[] data = new byte [optLength];
872                                         Marshal.Copy (optional, data, 0, optLength);
873                                         _optional = SecurityManager.Decode (data);
874                                 }
875                                 if (refLength > 0) {
876                                         byte[] data = new byte [refLength];
877                                         Marshal.Copy (refused, data, 0, refLength);
878                                         _refuse = SecurityManager.Decode (data);
879                                 }
880                         }
881                 }
882                 
883 #if NET_4_0
884                 public virtual PermissionSet PermissionSet {
885                         get { return this.GrantedPermissionSet; }
886                 }
887                 
888                 public virtual SecurityRuleSet SecurityRuleSet {
889                         get { throw CreateNIE (); }
890                 }
891 #endif
892
893 #endif
894
895 #if NET_4_0
896                 static Exception CreateNIE ()
897                 {
898                         return new NotImplementedException ("Derived classes must implement it");
899                 }
900                 
901                 public virtual IList<CustomAttributeData> GetCustomAttributesData ()
902                 {
903                         return CustomAttributeData.GetCustomAttributes (this);
904                 }
905
906                 [MonoTODO]
907                 public bool IsFullyTrusted {
908                         get { return true; }
909                 }
910
911                 public virtual Type GetType (string name, bool throwOnError, bool ignoreCase)
912                 {
913                         throw CreateNIE ();
914                 }
915
916                 public virtual Module GetModule (String name)
917                 {
918                         throw CreateNIE ();
919                 }
920
921                 public virtual AssemblyName[] GetReferencedAssemblies ()
922                 {
923                         throw CreateNIE ();
924                 }
925
926                 public virtual Module[] GetModules (bool getResourceModules)
927                 {
928                         throw CreateNIE ();
929                 }
930
931                 [MonoTODO ("Always returns the same as GetModules")]
932                 public virtual Module[] GetLoadedModules (bool getResourceModules)
933                 {
934                         throw CreateNIE ();
935                 }
936
937                 public virtual Assembly GetSatelliteAssembly (CultureInfo culture)
938                 {
939                         throw CreateNIE ();
940                 }
941
942                 public virtual Assembly GetSatelliteAssembly (CultureInfo culture, Version version)
943                 {
944                         throw CreateNIE ();
945                 }
946
947                 public virtual Module ManifestModule {
948                         get { throw CreateNIE (); }
949                 }
950
951                 public virtual bool GlobalAssemblyCache {
952                         get { throw CreateNIE (); }
953                 }
954
955                 public virtual bool IsDynamic {
956                         get { return false; }
957                 }
958
959                 public static bool operator == (Assembly left, Assembly right)
960                 {
961                         if ((object)left == (object)right)
962                                 return true;
963                         if ((object)left == null ^ (object)right == null)
964                                 return false;
965                         return left.Equals (right);
966                 }
967
968                 public static bool operator != (Assembly left, Assembly right)
969                 {
970                         if ((object)left == (object)right)
971                                 return false;
972                         if ((object)left == null ^ (object)right == null)
973                                 return true;
974                         return !left.Equals (right);
975                 }
976 #endif
977         }
978 }