2 // System.Reflection/Assembly.cs
5 // Paolo Molaro (lupus@ximian.com)
7 // (C) 2001 Ximian, Inc. http://www.ximian.com
8 // Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
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:
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
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.Security;
31 using System.Security.Policy;
32 using System.Security.Permissions;
33 using System.Runtime.Serialization;
34 using System.Reflection.Emit;
36 using System.Globalization;
37 using System.Runtime.CompilerServices;
38 using System.Runtime.InteropServices;
39 using System.Collections;
40 using System.Configuration.Assemblies;
44 namespace System.Reflection {
48 [ComDefaultInterfaceAttribute (typeof (_Assembly))]
51 [ClassInterface(ClassInterfaceType.None)]
52 public class Assembly : System.Reflection.ICustomAttributeProvider, _Assembly,
53 System.Security.IEvidenceFactory, System.Runtime.Serialization.ISerializable {
55 internal class ResolveEventHolder {
56 public event ModuleResolveEventHandler ModuleResolve;
59 // Note: changes to fields must be reflected in _MonoReflectionAssembly struct (object-internals.h)
60 private IntPtr _mono_assembly;
62 private ResolveEventHolder resolve_event_holder;
63 private Evidence _evidence;
64 internal PermissionSet _minimum; // for SecurityAction.RequestMinimum
65 internal PermissionSet _optional; // for SecurityAction.RequestOptional
66 internal PermissionSet _refuse; // for SecurityAction.RequestRefuse
67 private PermissionSet _granted; // for the resolved assembly granted permissions
68 private PermissionSet _denied; // for the resolved assembly denied permissions
69 private bool fromByteArray;
73 resolve_event_holder = new ResolveEventHolder ();
77 // We can't store the event directly in this class, since the
78 // compiler would silently insert the fields before _mono_assembly
80 public event ModuleResolveEventHandler ModuleResolve {
81 [SecurityPermission (SecurityAction.LinkDemand, ControlAppDomain = true)]
83 resolve_event_holder.ModuleResolve += value;
85 [SecurityPermission (SecurityAction.LinkDemand, ControlAppDomain = true)]
87 resolve_event_holder.ModuleResolve -= value;
91 [MethodImplAttribute (MethodImplOptions.InternalCall)]
92 private extern string get_code_base ();
94 [MethodImplAttribute (MethodImplOptions.InternalCall)]
95 private extern string get_location ();
97 [MethodImplAttribute (MethodImplOptions.InternalCall)]
98 private extern string InternalImageRuntimeVersion ();
100 [MethodImplAttribute (MethodImplOptions.InternalCall)]
101 private extern bool get_global_assembly_cache ();
103 // SECURITY: this should be the only caller to icall get_code_base
104 private string GetCodeBase ()
106 string cb = get_code_base ();
107 if (SecurityManager.SecurityEnabled) {
108 // we cannot divulge local file informations
109 if (String.Compare ("FILE://", 0, cb, 0, 7, true, CultureInfo.InvariantCulture) == 0) {
110 string file = cb.Substring (7);
111 new FileIOPermission (FileIOPermissionAccess.PathDiscovery, file).Demand ();
117 public virtual string CodeBase {
118 get { return GetCodeBase (); }
121 public virtual string EscapedCodeBase {
122 get { return Uri.EscapeString (GetCodeBase (), false, true, true); }
125 public virtual string FullName {
128 // FIXME: This is wrong, but it gets us going
129 // in the compiler for now
135 public virtual extern MethodInfo EntryPoint {
136 [MethodImplAttribute (MethodImplOptions.InternalCall)]
140 public virtual Evidence Evidence {
141 [SecurityPermission (SecurityAction.Demand, ControlEvidence = true)]
142 get { return UnprotectedGetEvidence (); }
145 // note: the security runtime requires evidences but may be unable to do so...
146 internal Evidence UnprotectedGetEvidence ()
148 // if the host (runtime) hasn't provided it's own evidence...
149 if (_evidence == null) {
150 // ... we will provide our own
152 _evidence = Evidence.GetDefaultHostEvidence (this);
158 public bool GlobalAssemblyCache {
160 return get_global_assembly_cache ();
164 internal bool FromByteArray {
165 set { fromByteArray = true; }
168 public virtual String Location {
173 string loc = get_location ();
174 if ((loc != String.Empty) && SecurityManager.SecurityEnabled) {
175 // we cannot divulge local file informations
176 new FileIOPermission (FileIOPermissionAccess.PathDiscovery, loc).Demand ();
184 public virtual string ImageRuntimeVersion {
186 return InternalImageRuntimeVersion ();
191 [SecurityPermission (SecurityAction.LinkDemand, SerializationFormatter = true)]
192 public virtual void GetObjectData (SerializationInfo info, StreamingContext context)
195 throw new ArgumentNullException ("info");
197 UnitySerializationHolder.GetAssemblyData (this, info, context);
201 public new Type GetType ()
203 return base.GetType ();
207 public virtual bool IsDefined (Type attributeType, bool inherit)
209 return MonoCustomAttrs.IsDefined (this, attributeType, inherit);
212 public virtual object [] GetCustomAttributes (bool inherit)
214 return MonoCustomAttrs.GetCustomAttributes (this, inherit);
217 public virtual object [] GetCustomAttributes (Type attributeType, bool inherit)
219 return MonoCustomAttrs.GetCustomAttributes (this, attributeType, inherit);
222 [MethodImplAttribute (MethodImplOptions.InternalCall)]
223 private extern object GetFilesInternal (String name, bool getResourceModules);
225 public virtual FileStream[] GetFiles ()
227 return GetFiles (false);
230 public virtual FileStream [] GetFiles (bool getResourceModules)
232 string[] names = (string[]) GetFilesInternal (null, getResourceModules);
234 return new FileStream [0];
236 FileStream[] res = new FileStream [names.Length];
237 for (int i = 0; i < names.Length; ++i)
238 res [i] = new FileStream (names [i], FileMode.Open, FileAccess.Read);
242 public virtual FileStream GetFile (String name)
245 throw new ArgumentNullException ("name");
246 if (name.Length == 0)
247 throw new ArgumentException ("name");
249 string filename = (string)GetFilesInternal (name, true);
250 if (filename != null)
251 return new FileStream (filename, FileMode.Open, FileAccess.Read);
256 [MethodImplAttribute (MethodImplOptions.InternalCall)]
257 internal extern IntPtr GetManifestResourceInternal (String name, out int size, out Module module);
259 public virtual Stream GetManifestResourceStream (String name)
262 throw new ArgumentNullException ("name");
264 throw new ArgumentException ("name cannot have zero length.");
266 ManifestResourceInfo info = GetManifestResourceInfo (name);
270 if (info.ReferencedAssembly != null)
271 return info.ReferencedAssembly.GetManifestResourceStream (name);
272 if ((info.FileName != null) && (info.ResourceLocation == 0)) {
273 string filename = Path.Combine (Path.GetDirectoryName (Location),
275 return new FileStream (filename, FileMode.Open, FileAccess.Read);
280 IntPtr data = GetManifestResourceInternal (name, out size, out module);
281 if (data == (IntPtr) 0)
284 IntPtrStream stream = new IntPtrStream (data, size);
286 * The returned pointer points inside metadata, so
287 * we have to increase the refcount of the module, and decrease
288 * it when the stream is finalized.
290 stream.Closed += new EventHandler (new ResourceCloseHandler (module).OnClose);
295 public virtual Stream GetManifestResourceStream (Type type, String name)
303 if ((ns == null) || (ns == ""))
304 return GetManifestResourceStream (name);
306 return GetManifestResourceStream (ns + "." + name);
309 [MethodImplAttribute (MethodImplOptions.InternalCall)]
310 private extern Type[] GetTypes (bool exportedOnly);
312 public virtual Type[] GetTypes ()
314 return GetTypes (false);
317 public virtual Type[] GetExportedTypes ()
319 return GetTypes (true);
322 public virtual Type GetType (String name, Boolean throwOnError)
324 return GetType (name, throwOnError, false);
327 public virtual Type GetType (String name) {
328 return GetType (name, false, false);
331 [MethodImplAttribute (MethodImplOptions.InternalCall)]
332 internal extern Type InternalGetType (Module module, String name, Boolean throwOnError, Boolean ignoreCase);
334 public Type GetType (string name, bool throwOnError, bool ignoreCase)
337 throw new ArgumentNullException (name);
339 return InternalGetType (null, name, throwOnError, ignoreCase);
342 [MethodImplAttribute (MethodImplOptions.InternalCall)]
343 internal extern static void InternalGetAssemblyName (string assemblyFile, AssemblyName aname);
345 [MethodImplAttribute (MethodImplOptions.InternalCall)]
346 static extern void FillName (Assembly ass, AssemblyName aname);
348 [MonoTODO ("true == not supported")]
349 public virtual AssemblyName GetName (Boolean copiedName)
351 // CodeBase, which is restricted, will be copied into the AssemblyName object so...
352 if (SecurityManager.SecurityEnabled) {
353 GetCodeBase (); // this will ensure the Demand is made
355 return UnprotectedGetName ();
358 public virtual AssemblyName GetName ()
360 return GetName (false);
363 // the security runtime requires access to the assemblyname (e.g. to get the strongname)
364 internal virtual AssemblyName UnprotectedGetName ()
366 AssemblyName aname = new AssemblyName ();
367 FillName (this, aname);
371 public override string ToString ()
373 // note: ToString work without requiring CodeBase (so no checks are needed)
374 AssemblyName aname = new AssemblyName ();
375 FillName (this, aname);
376 return aname.ToString ();
379 public static String CreateQualifiedName (String assemblyName, String typeName)
381 return typeName + ", " + assemblyName;
384 public static Assembly GetAssembly (Type type)
387 return type.Assembly;
388 throw new ArgumentNullException ("type");
392 [MethodImplAttribute (MethodImplOptions.InternalCall)]
393 public static extern Assembly GetEntryAssembly();
395 public Assembly GetSatelliteAssembly (CultureInfo culture)
397 return GetSatelliteAssembly (culture, null);
400 public Assembly GetSatelliteAssembly (CultureInfo culture, Version version)
403 throw new ArgumentException ("culture");
405 AssemblyName aname = GetName (true);
407 aname.Version = version;
409 aname.CultureInfo = culture;
410 aname.Name = aname.Name + ".resources";
414 [MethodImplAttribute (MethodImplOptions.InternalCall)]
415 private extern static Assembly LoadFrom (String assemblyFile, bool refonly);
417 public static Assembly LoadFrom (String assemblyFile)
419 return LoadFrom (assemblyFile, false);
422 public static Assembly LoadFrom (String assemblyFile, Evidence securityEvidence)
424 Assembly a = LoadFrom (assemblyFile, false);
425 if ((a != null) && (securityEvidence != null)) {
426 // merge evidence (i.e. replace defaults with provided evidences)
427 a.Evidence.Merge (securityEvidence);
435 public static Assembly LoadFrom (String assemblyFile, Evidence securityEvidence, byte[] hashValue, AssemblyHashAlgorithm hashAlgorithm)
437 if (assemblyFile == null)
438 throw new ArgumentNullException ("assemblyFile");
439 if (assemblyFile == String.Empty)
440 throw new ArgumentException ("Name can't be the empty string", "assemblyFile");
441 throw new NotImplementedException ();
445 public static Assembly LoadFile (String path, Evidence securityEvidence) {
447 throw new ArgumentNullException ("path");
448 if (path == String.Empty)
449 throw new ArgumentException ("Path can't be empty", "path");
450 // FIXME: Make this do the right thing
451 return LoadFrom (path, securityEvidence);
454 public static Assembly LoadFile (String path) {
455 return LoadFile (path, null);
459 public static Assembly Load (String assemblyString)
461 return AppDomain.CurrentDomain.Load (assemblyString);
464 public static Assembly Load (String assemblyString, Evidence assemblySecurity)
466 return AppDomain.CurrentDomain.Load (assemblyString, assemblySecurity);
469 public static Assembly Load (AssemblyName assemblyRef)
471 return AppDomain.CurrentDomain.Load (assemblyRef);
474 public static Assembly Load (AssemblyName assemblyRef, Evidence assemblySecurity)
476 return AppDomain.CurrentDomain.Load (assemblyRef, assemblySecurity);
479 public static Assembly Load (Byte[] rawAssembly)
481 return AppDomain.CurrentDomain.Load (rawAssembly);
484 public static Assembly Load (Byte[] rawAssembly, Byte[] rawSymbolStore)
486 return AppDomain.CurrentDomain.Load (rawAssembly, rawSymbolStore);
489 public static Assembly Load (Byte[] rawAssembly, Byte[] rawSymbolStore,
490 Evidence securityEvidence)
492 return AppDomain.CurrentDomain.Load (rawAssembly, rawSymbolStore, securityEvidence);
496 public static Assembly ReflectionOnlyLoad (byte[] rawAssembly)
498 return AppDomain.CurrentDomain.Load (rawAssembly, null, null, true);
501 public static Assembly ReflectionOnlyLoad (string assemblyName)
503 return AppDomain.CurrentDomain.Load (assemblyName, null, true);
506 public static Assembly ReflectionOnlyLoadFrom (string assemblyFile)
508 if (assemblyFile == null)
509 throw new ArgumentNullException ("assemblyFile");
511 return LoadFrom (assemblyFile, true);
518 public static Assembly LoadWithPartialName (string partialName)
520 return LoadWithPartialName (partialName, null);
524 public Module LoadModule (string moduleName, byte [] rawModule)
526 throw new NotImplementedException ();
530 public Module LoadModule (string moduleName, byte [] rawModule, byte [] rawSymbolStore)
532 throw new NotImplementedException ();
535 [MethodImplAttribute (MethodImplOptions.InternalCall)]
536 private static extern Assembly load_with_partial_name (string name, Evidence e);
541 public static Assembly LoadWithPartialName (string partialName, Evidence securityEvidence)
543 return LoadWithPartialName (partialName, securityEvidence, true);
547 * LAMESPEC: It is possible for this method to throw exceptions IF the name supplied
548 * is a valid gac name and contains filesystem entry charachters at the end of the name
549 * ie System/// will throw an exception. However ////System will not as that is canocolized
553 // FIXME: LoadWithPartialName must look cache (no CAS) or read from disk (CAS)
554 internal static Assembly LoadWithPartialName (string partialName, Evidence securityEvidence, bool oldBehavior)
557 throw new NotImplementedException ();
559 if (partialName == null)
560 throw new NullReferenceException ();
562 return load_with_partial_name (partialName, securityEvidence);
565 public Object CreateInstance (String typeName)
567 return CreateInstance (typeName, false);
570 public Object CreateInstance (String typeName, Boolean ignoreCase)
572 Type t = GetType (typeName, false, ignoreCase);
577 return Activator.CreateInstance (t);
578 } catch (InvalidOperationException) {
579 throw new ArgumentException ("It is illegal to invoke a method on a Type loaded via ReflectionOnly methods.");
583 public Object CreateInstance (String typeName, Boolean ignoreCase,
584 BindingFlags bindingAttr, Binder binder,
585 Object[] args, CultureInfo culture,
586 Object[] activationAttributes)
588 Type t = GetType (typeName, false, ignoreCase);
593 return Activator.CreateInstance (t, bindingAttr, binder, args, culture, activationAttributes);
594 } catch (InvalidOperationException) {
595 throw new ArgumentException ("It is illegal to invoke a method on a Type loaded via ReflectionOnly methods.");
599 public Module[] GetLoadedModules ()
601 return GetLoadedModules (false);
605 public Module[] GetLoadedModules (bool getResourceModules)
607 // Currently, the two sets of modules are equal
608 return GetModules (getResourceModules);
611 public Module[] GetModules ()
613 return GetModules (false);
616 public Module GetModule (String name)
619 throw new ArgumentNullException ("name");
621 throw new ArgumentException ("Name can't be empty");
623 Module[] modules = GetModules (true);
624 foreach (Module module in modules) {
625 if (module.ScopeName == name)
632 [MethodImplAttribute (MethodImplOptions.InternalCall)]
633 internal extern Module[] GetModulesInternal ();
635 public Module[] GetModules (bool getResourceModules) {
636 Module[] modules = GetModulesInternal ();
638 if (!getResourceModules) {
639 ArrayList result = new ArrayList (modules.Length);
640 foreach (Module m in modules)
641 if (!m.IsResource ())
643 return (Module[])result.ToArray (typeof (Module));
649 [MethodImplAttribute (MethodImplOptions.InternalCall)]
650 internal extern string[] GetNamespaces ();
652 [MethodImplAttribute (MethodImplOptions.InternalCall)]
653 public extern virtual String[] GetManifestResourceNames ();
655 [MethodImplAttribute (MethodImplOptions.InternalCall)]
656 public extern static Assembly GetExecutingAssembly ();
658 [MethodImplAttribute (MethodImplOptions.InternalCall)]
659 public extern static Assembly GetCallingAssembly ();
661 [MethodImplAttribute (MethodImplOptions.InternalCall)]
662 public extern AssemblyName[] GetReferencedAssemblies ();
664 [MethodImplAttribute (MethodImplOptions.InternalCall)]
665 private extern bool GetManifestResourceInfoInternal (String name, ManifestResourceInfo info);
667 public virtual ManifestResourceInfo GetManifestResourceInfo (String resourceName)
669 if (resourceName == null)
670 throw new ArgumentNullException ("resourceName");
671 if (resourceName == "")
672 throw new ArgumentException ("String cannot have zero length.");
673 ManifestResourceInfo result = new ManifestResourceInfo ();
674 bool found = GetManifestResourceInfoInternal (resourceName, result);
681 private class ResourceCloseHandler {
685 public ResourceCloseHandler (Module module) {
686 this.module = module;
689 public void OnClose (object sender, EventArgs e) {
690 // The module dtor will take care of things
696 // The following functions are only for the Mono Debugger.
699 [MethodImplAttribute (MethodImplOptions.InternalCall)]
700 internal static extern MethodBase MonoDebugger_GetMethod (Assembly assembly, int token);
702 [MethodImplAttribute (MethodImplOptions.InternalCall)]
703 internal static extern int MonoDebugger_GetMethodToken (MethodBase method);
705 [MethodImplAttribute (MethodImplOptions.InternalCall)]
706 internal static extern Type MonoDebugger_GetLocalTypeFromSignature (Assembly assembly, byte[] signature);
708 [MethodImplAttribute (MethodImplOptions.InternalCall)]
709 internal static extern Type MonoDebugger_GetType (Assembly assembly, int token);
711 [MethodImplAttribute (MethodImplOptions.InternalCall)]
712 internal static extern string MonoDebugger_CheckRuntimeVersion (string filename);
714 [MethodImplAttribute (MethodImplOptions.InternalCall)]
715 internal static extern string MonoDebugger_GetMethodIndex (MethodBase method);
717 [MethodImplAttribute (MethodImplOptions.InternalCall)]
718 internal static extern Type MonoDebugger_MakeArrayType (Type type, int rank);
720 [MethodImplAttribute (MethodImplOptions.InternalCall)]
721 internal static extern int MonoDebugger_GetTypeToken (Type type);
726 public long HostContext {
731 [Obsolete ("Please use Assembly.ManifestModule.GetPEKind() instead - this will be removed before Whidbey ships.")]
732 public ImageFileMachine ImageFileMachine {
734 ImageFileMachine machine;
735 PortableExecutableKinds kind;
736 ModuleHandle handle = ManifestModule.ModuleHandle;
737 handle.GetPEKind (out kind, out machine);
743 public extern Module ManifestModule {
744 [MethodImplAttribute (MethodImplOptions.InternalCall)]
749 [Obsolete ("This method has been deprecated and will be removed before v2.0 RTM is released.")]
750 public extern int MetadataToken {
751 [MethodImplAttribute (MethodImplOptions.InternalCall)]
756 [Obsolete ("Please use Assembly.ManifestModule.GetPEKind() instead - this will be removed before Whidbey ships.")]
757 public PortableExecutableKinds PortableExecutableKinds {
759 ImageFileMachine machine;
760 PortableExecutableKinds kind;
761 ModuleHandle handle = ManifestModule.ModuleHandle;
762 handle.GetPEKind (out kind, out machine);
768 public virtual extern bool ReflectionOnly {
769 [MethodImplAttribute (MethodImplOptions.InternalCall)]
774 // Code Access Security
776 internal void Resolve ()
779 // FIXME: As we (currently) delay the resolution until the first CAS
780 // Demand it's too late to evaluate the Minimum permission set as a
781 // condition to load the assembly into the AppDomain
782 LoadAssemblyPermissions ();
783 Evidence e = new Evidence (UnprotectedGetEvidence ()); // we need a copy to add PRE
784 e.AddHost (new PermissionRequestEvidence (_minimum, _optional, _refuse));
785 _granted = SecurityManager.ResolvePolicy (e,
786 _minimum, _optional, _refuse, out _denied);
790 internal PermissionSet GrantedPermissionSet {
792 if (_granted == null) {
793 if (SecurityManager.ResolvingPolicyLevel != null) {
794 if (SecurityManager.ResolvingPolicyLevel.IsFullTrustAssembly (this))
795 return DefaultPolicies.FullTrust;
797 return null; // we can't resolve during resolution
805 internal PermissionSet DeniedPermissionSet {
807 // yes we look for granted, as denied may be null
808 if (_granted == null) {
809 if (SecurityManager.ResolvingPolicyLevel != null) {
810 if (SecurityManager.ResolvingPolicyLevel.IsFullTrustAssembly (this))
813 return DefaultPolicies.FullTrust; // deny unrestricted
821 [MethodImplAttribute (MethodImplOptions.InternalCall)]
822 extern internal static bool LoadPermissions (Assembly a,
823 ref IntPtr minimum, ref int minLength,
824 ref IntPtr optional, ref int optLength,
825 ref IntPtr refused, ref int refLength);
827 // Support for SecurityAction.RequestMinimum, RequestOptional and RequestRefuse
828 private void LoadAssemblyPermissions ()
830 IntPtr minimum = IntPtr.Zero, optional = IntPtr.Zero, refused = IntPtr.Zero;
831 int minLength = 0, optLength = 0, refLength = 0;
832 if (LoadPermissions (this, ref minimum, ref minLength, ref optional,
833 ref optLength, ref refused, ref refLength)) {
835 // Note: no need to cache these permission sets as they will only be created once
836 // at assembly resolution time.
838 byte[] data = new byte [minLength];
839 Marshal.Copy (minimum, data, 0, minLength);
840 _minimum = SecurityManager.Decode (data);
843 byte[] data = new byte [optLength];
844 Marshal.Copy (optional, data, 0, optLength);
845 _optional = SecurityManager.Decode (data);
848 byte[] data = new byte [refLength];
849 Marshal.Copy (refused, data, 0, refLength);
850 _refuse = SecurityManager.Decode (data);