**** Merged from MCS ****
[mono-project.git] / mcs / class / corlib / System.Reflection / Assembly.cs
blob0ac16a33d34a737ca7b1ccbbceb1d62abd783a66
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 Novell, Inc (http://www.novell.com)
9 //
10 // Permission is hereby granted, free of charge, to any person obtaining
11 // a copy of this software and associated documentation files (the
12 // "Software"), to deal in the Software without restriction, including
13 // without limitation the rights to use, copy, modify, merge, publish,
14 // distribute, sublicense, and/or sell copies of the Software, and to
15 // permit persons to whom the Software is furnished to do so, subject to
16 // the following conditions:
17 //
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
20 //
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 using System;
31 using System.Security;
32 using System.Security.Policy;
33 using System.Security.Permissions;
34 using System.Runtime.Serialization;
35 using System.Reflection.Emit;
36 using System.IO;
37 using System.Globalization;
38 using System.Runtime.CompilerServices;
39 using System.Runtime.InteropServices;
40 using System.Collections;
41 using System.Configuration.Assemblies;
43 namespace System.Reflection {
45 internal class ResolveEventHolder {
46 public event ModuleResolveEventHandler ModuleResolve;
49 [Serializable]
50 [ClassInterface(ClassInterfaceType.AutoDual)]
51 public class Assembly : System.Reflection.ICustomAttributeProvider,
52 System.Security.IEvidenceFactory, System.Runtime.Serialization.ISerializable {
54 // Note: changes to fields must be reflected in _MonoReflectionAssembly struct (object-internals.h)
55 private IntPtr _mono_assembly;
57 private ResolveEventHolder resolve_event_holder;
58 private Evidence _evidence;
59 internal PermissionSet _minimum; // for SecurityAction.RequestMinimum
60 internal PermissionSet _optional; // for SecurityAction.RequestOptional
61 internal PermissionSet _refuse; // for SecurityAction.RequestRefuse
62 private PermissionSet _granted; // for the resolved assembly granted permissions
63 private PermissionSet _denied; // for the resolved assembly denied permissions
65 internal Assembly ()
67 resolve_event_holder = new ResolveEventHolder ();
71 // We can't store the event directly in this class, since the
72 // compile would silently insert the fields before _mono_assembly
74 public event ModuleResolveEventHandler ModuleResolve {
75 add {
76 resolve_event_holder.ModuleResolve -= value;
78 remove {
79 resolve_event_holder.ModuleResolve -= value;
83 [MethodImplAttribute (MethodImplOptions.InternalCall)]
84 private extern string get_code_base ();
86 [MethodImplAttribute (MethodImplOptions.InternalCall)]
87 private extern string get_location ();
89 [MethodImplAttribute (MethodImplOptions.InternalCall)]
90 private extern string InternalImageRuntimeVersion ();
92 [MethodImplAttribute (MethodImplOptions.InternalCall)]
93 private extern bool get_global_assembly_cache ();
95 public virtual string CodeBase {
96 get {
97 return get_code_base ();
101 internal virtual string CopiedCodeBase {
102 get {
103 return get_code_base ();
107 [MonoTODO]
108 public virtual string EscapedCodeBase {
109 get {
110 //FIXME: escape characters -> Uri
111 return get_code_base ();
115 public virtual string FullName {
116 get {
118 // FIXME: This is wrong, but it gets us going
119 // in the compiler for now
121 return GetName (false).ToString ();
125 public virtual extern MethodInfo EntryPoint {
126 [MethodImplAttribute (MethodImplOptions.InternalCall)]
127 get;
130 public virtual Evidence Evidence {
131 get {
132 // if the host (runtime) hasn't provided it's own evidence...
133 if (_evidence == null) {
134 // ... we will provide our own
135 lock (this) {
136 _evidence = Evidence.GetDefaultHostEvidence (this);
139 return _evidence;
143 public bool GlobalAssemblyCache {
144 get {
145 return get_global_assembly_cache ();
149 public virtual String Location {
150 get {
151 return get_location ();
155 #if NET_1_1
156 [ComVisible (false)]
157 public virtual string ImageRuntimeVersion {
158 get {
159 return InternalImageRuntimeVersion ();
162 #endif
164 public virtual void GetObjectData (SerializationInfo info, StreamingContext context)
166 UnitySerializationHolder.GetAssemblyData (this, info, context);
169 public virtual bool IsDefined (Type attributeType, bool inherit)
171 return MonoCustomAttrs.IsDefined (this, attributeType, inherit);
174 public virtual object [] GetCustomAttributes (bool inherit)
176 return MonoCustomAttrs.GetCustomAttributes (this, inherit);
179 public virtual object [] GetCustomAttributes (Type attributeType, bool inherit)
181 return MonoCustomAttrs.GetCustomAttributes (this, attributeType, inherit);
184 [MethodImplAttribute (MethodImplOptions.InternalCall)]
185 private extern object GetFilesInternal (String name, bool getResourceModules);
187 public virtual FileStream[] GetFiles ()
189 return GetFiles (false);
192 public virtual FileStream [] GetFiles (bool getResourceModules)
194 string[] names = (string[]) GetFilesInternal (null, getResourceModules);
195 if (names == null)
196 return new FileStream [0];
198 FileStream[] res = new FileStream [names.Length];
199 for (int i = 0; i < names.Length; ++i)
200 res [i] = new FileStream (names [i], FileMode.Open, FileAccess.Read);
201 return res;
204 public virtual FileStream GetFile (String name)
206 if (name == null)
207 throw new ArgumentNullException ("name");
208 if (name.Length == 0)
209 throw new ArgumentException ("name");
211 string filename = (string)GetFilesInternal (name, true);
212 if (filename != null)
213 return new FileStream (filename, FileMode.Open, FileAccess.Read);
214 else
215 return null;
218 [MethodImplAttribute (MethodImplOptions.InternalCall)]
219 private extern IntPtr GetManifestResourceInternal (String name, out int size, out Module module);
221 public virtual Stream GetManifestResourceStream (String name)
223 if (name == null)
224 throw new ArgumentNullException ("name");
225 if (name == "")
226 throw new ArgumentException ("name cannot have zero length.");
228 ManifestResourceInfo info = GetManifestResourceInfo (name);
229 if (info == null)
230 return null;
232 if (info.ReferencedAssembly != null)
233 return info.ReferencedAssembly.GetManifestResourceStream (name);
234 if ((info.FileName != null) && (info.ResourceLocation == 0)) {
235 string filename = Path.Combine (Path.GetDirectoryName (Location),
236 info.FileName);
237 return new FileStream (filename, FileMode.Open, FileAccess.Read);
240 int size;
241 Module module;
242 IntPtr data = GetManifestResourceInternal (name, out size, out module);
243 if (data == (IntPtr) 0)
244 return null;
245 else {
246 IntPtrStream stream = new IntPtrStream (data, size);
248 * The returned pointer points inside metadata, so
249 * we have to increase the refcount of the module, and decrease
250 * it when the stream is finalized.
252 stream.Closed += new EventHandler (new ResourceCloseHandler (module).OnClose);
253 return stream;
257 public virtual Stream GetManifestResourceStream (Type type, String name)
259 string ns;
260 if (type != null)
261 ns = type.Namespace;
262 else
263 ns = null;
265 if ((ns == null) || (ns == ""))
266 return GetManifestResourceStream (name);
267 else
268 return GetManifestResourceStream (ns + "." + name);
271 [MethodImplAttribute (MethodImplOptions.InternalCall)]
272 private extern Type[] GetTypes (bool exportedOnly);
274 public virtual Type[] GetTypes ()
276 return GetTypes (false);
279 public virtual Type[] GetExportedTypes ()
281 return GetTypes (true);
284 public virtual Type GetType (String name, Boolean throwOnError)
286 return GetType (name, throwOnError, false);
289 public virtual Type GetType (String name) {
290 return GetType (name, false, false);
293 [MethodImplAttribute (MethodImplOptions.InternalCall)]
294 internal extern Type InternalGetType (Module module, String name, Boolean throwOnError, Boolean ignoreCase);
296 public Type GetType (string name, bool throwOnError, bool ignoreCase)
298 if (name == null)
299 throw new ArgumentNullException (name);
301 return InternalGetType (null, name, throwOnError, ignoreCase);
304 [MethodImplAttribute (MethodImplOptions.InternalCall)]
305 internal extern static void InternalGetAssemblyName (string assemblyFile, AssemblyName aname);
307 [MethodImplAttribute (MethodImplOptions.InternalCall)]
308 static extern void FillName (Assembly ass, AssemblyName aname);
310 [MonoTODO ("true == not supported")]
311 public virtual AssemblyName GetName (Boolean copiedName)
313 AssemblyName aname = new AssemblyName ();
314 FillName (this, aname);
315 return aname;
318 public virtual AssemblyName GetName ()
320 return GetName (false);
323 public override String ToString ()
325 return GetName ().ToString ();
328 public static String CreateQualifiedName (String assemblyName, String typeName)
330 return typeName + ", " + assemblyName;
333 public static Assembly GetAssembly (Type type)
335 if (type != null)
336 return type.Assembly;
337 throw new ArgumentNullException ("type");
341 [MethodImplAttribute (MethodImplOptions.InternalCall)]
342 public static extern Assembly GetEntryAssembly();
344 public Assembly GetSatelliteAssembly (CultureInfo culture)
346 return GetSatelliteAssembly (culture, null);
349 public Assembly GetSatelliteAssembly (CultureInfo culture, Version version)
351 if (culture == null)
352 throw new ArgumentException ("culture");
354 AssemblyName aname = GetName (true);
355 if (version != null)
356 aname.Version = version;
358 aname.CultureInfo = culture;
359 aname.Name = aname.Name + ".resources";
360 return Load (aname);
363 [MethodImplAttribute (MethodImplOptions.InternalCall)]
364 public extern static Assembly LoadFrom (String assemblyFile);
366 public static Assembly LoadFrom (String assemblyFile, Evidence securityEvidence)
368 Assembly a = LoadFrom (assemblyFile);
369 if ((a != null) && (securityEvidence != null)) {
370 // merge evidence (i.e. replace defaults with provided evidences)
371 a.Evidence.Merge (securityEvidence);
373 return a;
376 #if NET_1_1
378 [MonoTODO]
379 public static Assembly LoadFrom (String assemblyFile, Evidence securityEvidence, byte[] hashValue, AssemblyHashAlgorithm hashAlgorithm)
381 if (assemblyFile == null)
382 throw new ArgumentNullException ("assemblyFile");
383 if (assemblyFile == String.Empty)
384 throw new ArgumentException ("Name can't be the empty string", "assemblyFile");
385 throw new NotImplementedException ();
388 [MonoTODO]
389 public static Assembly LoadFile (String path, Evidence securityEvidence) {
390 if (path == null)
391 throw new ArgumentNullException ("path");
392 if (path == String.Empty)
393 throw new ArgumentException ("Path can't be empty", "path");
394 // FIXME: Make this do the right thing
395 return LoadFrom (path, securityEvidence);
398 public static Assembly LoadFile (String path) {
399 return LoadFile (path, null);
401 #endif
403 public static Assembly Load (String assemblyString)
405 return AppDomain.CurrentDomain.Load (assemblyString);
408 public static Assembly Load (String assemblyString, Evidence assemblySecurity)
410 return AppDomain.CurrentDomain.Load (assemblyString, assemblySecurity);
413 public static Assembly Load (AssemblyName assemblyRef)
415 return AppDomain.CurrentDomain.Load (assemblyRef);
418 public static Assembly Load (AssemblyName assemblyRef, Evidence assemblySecurity)
420 return AppDomain.CurrentDomain.Load (assemblyRef, assemblySecurity);
423 public static Assembly Load (Byte[] rawAssembly)
425 return AppDomain.CurrentDomain.Load (rawAssembly);
428 public static Assembly Load (Byte[] rawAssembly, Byte[] rawSymbolStore)
430 return AppDomain.CurrentDomain.Load (rawAssembly, rawSymbolStore);
433 public static Assembly Load (Byte[] rawAssembly, Byte[] rawSymbolStore,
434 Evidence securityEvidence)
436 return AppDomain.CurrentDomain.Load (rawAssembly, rawSymbolStore, securityEvidence);
439 #if NET_2_0
440 [MonoTODO]
441 public static Assembly ReflectionOnlyLoad (byte[] rawAssembly)
443 throw new NotImplementedException ();
446 [MonoTODO]
447 public static Assembly ReflectionOnlyLoad (string assemblyString) {
448 throw new NotImplementedException ();
451 [MonoTODO]
452 public static Assembly ReflectionOnlyLoadFrom (string assemblyFile) {
453 throw new NotImplementedException ();
455 #endif
457 #if NET_2_0
458 [Obsolete ("")]
459 #endif
460 public static Assembly LoadWithPartialName (string partialName)
462 return LoadWithPartialName (partialName, null);
465 [MonoTODO]
466 public Module LoadModule (string moduleName, byte [] rawModule)
468 throw new NotImplementedException ();
471 [MonoTODO]
472 public Module LoadModule (string moduleName, byte [] rawModule, byte [] rawSymbolStore)
474 throw new NotImplementedException ();
477 [MethodImplAttribute (MethodImplOptions.InternalCall)]
478 private static extern Assembly load_with_partial_name (string name, Evidence e);
480 #if NET_2_0
481 [Obsolete ("")]
482 #endif
483 public static Assembly LoadWithPartialName (string partialName, Evidence securityEvidence)
485 return LoadWithPartialName (partialName, securityEvidence, true);
489 * LAMESPEC: It is possible for this method to throw exceptions IF the name supplied
490 * is a valid gac name and contains filesystem entry charachters at the end of the name
491 * ie System/// will throw an exception. However ////System will not as that is canocolized
492 * out of the name.
494 #if NET_2_0
495 [Obsolete ("")]
496 [ComVisible (false)]
497 [MonoTODO]
498 public
499 #else
500 internal
501 #endif
502 static Assembly LoadWithPartialName (string partialName, Evidence securityEvidence, bool oldBehavior)
504 if (!oldBehavior)
505 throw new NotImplementedException ();
507 if (partialName == null)
508 throw new NullReferenceException ();
510 int ci = partialName.IndexOf (',');
511 if (ci > 0)
512 partialName = partialName.Substring (0, ci);
514 return load_with_partial_name (partialName, securityEvidence);
517 public Object CreateInstance (String typeName)
519 return CreateInstance (typeName, false);
522 public Object CreateInstance (String typeName, Boolean ignoreCase)
524 Type t = GetType (typeName, false, ignoreCase);
525 if (t == null)
526 return null;
528 return Activator.CreateInstance (t);
531 public Object CreateInstance (String typeName, Boolean ignoreCase,
532 BindingFlags bindingAttr, Binder binder,
533 Object[] args, CultureInfo culture,
534 Object[] activationAttributes)
536 Type t = GetType (typeName, false, ignoreCase);
537 if (t == null)
538 return null;
540 return Activator.CreateInstance (t, bindingAttr, binder, args, culture, activationAttributes);
543 public Module[] GetLoadedModules ()
545 return GetLoadedModules (false);
548 [MonoTODO]
549 public Module[] GetLoadedModules (bool getResourceModules)
551 // Currently, the two sets of modules are equal
552 return GetModules (getResourceModules);
555 public Module[] GetModules ()
557 return GetModules (false);
560 public Module GetModule (String name)
562 if (name == null)
563 throw new ArgumentNullException ("name");
564 if (name == "")
565 throw new ArgumentException ("Name can't be empty");
567 Module[] modules = GetModules (true);
568 foreach (Module module in modules) {
569 if (module.ScopeName == name)
570 return module;
573 return null;
576 [MethodImplAttribute (MethodImplOptions.InternalCall)]
577 internal extern Module[] GetModulesInternal ();
579 public Module[] GetModules (bool getResourceModules) {
580 Module[] modules = GetModulesInternal ();
582 if (!getResourceModules) {
583 ArrayList result = new ArrayList (modules.Length);
584 foreach (Module m in modules)
585 if (!m.IsResource ())
586 result.Add (m);
587 return (Module[])result.ToArray (typeof (Module));
589 else
590 return modules;
593 [MethodImplAttribute (MethodImplOptions.InternalCall)]
594 internal extern string[] GetNamespaces ();
596 [MethodImplAttribute (MethodImplOptions.InternalCall)]
597 public extern virtual String[] GetManifestResourceNames ();
599 [MethodImplAttribute (MethodImplOptions.InternalCall)]
600 public extern static Assembly GetExecutingAssembly ();
602 [MethodImplAttribute (MethodImplOptions.InternalCall)]
603 public extern static Assembly GetCallingAssembly ();
605 [MethodImplAttribute (MethodImplOptions.InternalCall)]
606 public extern AssemblyName[] GetReferencedAssemblies ();
608 [MethodImplAttribute (MethodImplOptions.InternalCall)]
609 private extern bool GetManifestResourceInfoInternal (String name, ManifestResourceInfo info);
611 public virtual ManifestResourceInfo GetManifestResourceInfo (String resourceName)
613 if (resourceName == null)
614 throw new ArgumentNullException ("resourceName");
615 if (resourceName == "")
616 throw new ArgumentException ("String cannot have zero length.");
617 ManifestResourceInfo result = new ManifestResourceInfo ();
618 bool found = GetManifestResourceInfoInternal (resourceName, result);
619 if (found)
620 return result;
621 else
622 return null;
625 private class ResourceCloseHandler {
627 Module module;
629 public ResourceCloseHandler (Module module) {
630 this.module = module;
633 public void OnClose (object sender, EventArgs e) {
634 // The module dtor will take care of things
635 module = null;
640 // The following functions are only for the Mono Debugger.
643 [MethodImplAttribute (MethodImplOptions.InternalCall)]
644 internal static extern MethodBase MonoDebugger_GetMethod (Assembly assembly, int token);
646 [MethodImplAttribute (MethodImplOptions.InternalCall)]
647 internal static extern int MonoDebugger_GetMethodToken (Assembly assembly, MethodBase method);
649 [MethodImplAttribute (MethodImplOptions.InternalCall)]
650 internal static extern Type MonoDebugger_GetLocalTypeFromSignature (Assembly assembly, byte[] signature);
652 [MethodImplAttribute (MethodImplOptions.InternalCall)]
653 internal static extern Type MonoDebugger_GetType (Assembly assembly, int token);
655 [MethodImplAttribute (MethodImplOptions.InternalCall)]
656 internal static extern string MonoDebugger_CheckRuntimeVersion (string filename);
658 #if NET_2_0
659 [MonoTODO]
660 [ComVisible (false)]
661 public long HostContext {
662 get { return 0; }
665 [ComVisible (false)]
666 public ImageFileMachine ImageFileMachine {
667 get {
668 ImageFileMachine machine;
669 PortableExecutableKind kind;
670 ModuleHandle handle = ManifestModule.ModuleHandle;
671 handle.GetPEKind (out kind, out machine);
672 return machine;
676 [ComVisible (false)]
677 public extern Module ManifestModule {
678 [MethodImplAttribute (MethodImplOptions.InternalCall)]
679 get;
682 [ComVisible (false)]
683 public extern int MetadataToken {
684 [MethodImplAttribute (MethodImplOptions.InternalCall)]
685 get;
688 [ComVisible (false)]
689 public PortableExecutableKind PortableExecutableKind {
690 get {
691 ImageFileMachine machine;
692 PortableExecutableKind kind;
693 ModuleHandle handle = ManifestModule.ModuleHandle;
694 handle.GetPEKind (out kind, out machine);
695 return kind;
699 [MonoTODO ("see ReflectionOnlyLoad")]
700 [ComVisible (false)]
701 public virtual bool ReflectionOnly {
702 get { return false; }
704 #endif
706 // Code Access Security
708 internal void Resolve ()
710 lock (this) {
711 _granted = SecurityManager.ResolvePolicy (Evidence, _minimum, _optional,
712 _refuse, out _denied);
714 #if false
715 Console.WriteLine ("Granted: {0}", _granted);
716 if (_denied != null)
717 Console.WriteLine ("Denied: {0}", _denied);
718 #endif
721 internal PermissionSet GrantedPermissionSet {
722 get {
723 if (_granted == null) {
724 Resolve ();
726 return _granted;
730 internal PermissionSet DeniedPermissionSet {
731 get {
732 // yes we look for granted, as denied may be null
733 if (_granted == null) {
734 Resolve ();
736 return _denied;
740 // Result isn't affected by overrides (like Assert, Deny and PermitOnly)
741 internal bool Demand (IPermission p)
743 Type t = p.GetType ();
745 // have we been explicitely denied this permission ?
746 if (_denied != null) {
747 IPermission denied = _denied.GetPermission (t);
748 if (denied != null) {
749 if (p.IsSubsetOf (denied))
750 return false;
754 // is it part of the optional permissions requested by the assembly ?
755 if (_optional != null) {
756 IPermission optional = _optional.GetPermission (t);
757 if (optional != null) {
758 // there is! so we can only request a subset of it
759 if (!p.IsSubsetOf (optional))
760 return false;
764 // don't check IUnrestrictedPermission if we have "Full Trust"
765 // note: that won't work for code identity permissions (e.g. Zone)
766 if ((p is IUnrestrictedPermission) && GrantedPermissionSet.IsUnrestricted ())
767 return true;
769 // finally does the resolved policy allow this requested permission ?
770 IPermission granted = GrantedPermissionSet.GetPermission (t);
771 if (granted != null) {
772 if (!p.IsSubsetOf (granted))
773 return false;
775 return true;
778 // Result isn't affected by overrides (like Assert, Deny and PermitOnly)
779 internal bool Demand (PermissionSet ps)
781 // have we been explicitely denied this permission ?
782 if (DeniedPermissionSet != null) {
783 if (ps.IsSubsetOf (DeniedPermissionSet)) {
784 return false;
788 // is it part of the optional permissions requested by the assembly ?
789 if (_optional != null) {
790 // there is! so we can only request a subset of it
791 if (!ps.IsSubsetOf (_optional)) {
792 return false;
796 return ps.IsSubsetOf (GrantedPermissionSet);