2 // System.Reflection/Assembly.cs
5 // Paolo Molaro (lupus@ximian.com)
7 // (C) 2001 Ximian, Inc. http://www.ximian.com
8 // Copyright (C) 2004 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.
31 using System.Security;
32 using System.Security.Policy;
33 using System.Security.Permissions;
34 using System.Runtime.Serialization;
35 using System.Reflection.Emit;
37 using System.Globalization;
38 using System.Runtime.CompilerServices;
39 using System.Runtime.InteropServices;
40 using System.Collections;
41 using System.Configuration.Assemblies;
45 namespace System.Reflection {
49 [ComDefaultInterfaceAttribute (typeof (_Assembly))]
52 [ClassInterface(ClassInterfaceType.None)]
53 public class Assembly : System.Reflection.ICustomAttributeProvider,
54 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);
200 public virtual bool IsDefined (Type attributeType, bool inherit)
202 return MonoCustomAttrs.IsDefined (this, attributeType, inherit);
205 public virtual object [] GetCustomAttributes (bool inherit)
207 return MonoCustomAttrs.GetCustomAttributes (this, inherit);
210 public virtual object [] GetCustomAttributes (Type attributeType, bool inherit)
212 return MonoCustomAttrs.GetCustomAttributes (this, attributeType, inherit);
215 [MethodImplAttribute (MethodImplOptions.InternalCall)]
216 private extern object GetFilesInternal (String name, bool getResourceModules);
218 public virtual FileStream[] GetFiles ()
220 return GetFiles (false);
223 public virtual FileStream [] GetFiles (bool getResourceModules)
225 string[] names = (string[]) GetFilesInternal (null, getResourceModules);
227 return new FileStream [0];
229 FileStream[] res = new FileStream [names.Length];
230 for (int i = 0; i < names.Length; ++i)
231 res [i] = new FileStream (names [i], FileMode.Open, FileAccess.Read);
235 public virtual FileStream GetFile (String name)
238 throw new ArgumentNullException ("name");
239 if (name.Length == 0)
240 throw new ArgumentException ("name");
242 string filename = (string)GetFilesInternal (name, true);
243 if (filename != null)
244 return new FileStream (filename, FileMode.Open, FileAccess.Read);
249 [MethodImplAttribute (MethodImplOptions.InternalCall)]
250 private extern IntPtr GetManifestResourceInternal (String name, out int size, out Module module);
252 public virtual Stream GetManifestResourceStream (String name)
255 throw new ArgumentNullException ("name");
257 throw new ArgumentException ("name cannot have zero length.");
259 ManifestResourceInfo info = GetManifestResourceInfo (name);
263 if (info.ReferencedAssembly != null)
264 return info.ReferencedAssembly.GetManifestResourceStream (name);
265 if ((info.FileName != null) && (info.ResourceLocation == 0)) {
266 string filename = Path.Combine (Path.GetDirectoryName (Location),
268 return new FileStream (filename, FileMode.Open, FileAccess.Read);
273 IntPtr data = GetManifestResourceInternal (name, out size, out module);
274 if (data == (IntPtr) 0)
277 IntPtrStream stream = new IntPtrStream (data, size);
279 * The returned pointer points inside metadata, so
280 * we have to increase the refcount of the module, and decrease
281 * it when the stream is finalized.
283 stream.Closed += new EventHandler (new ResourceCloseHandler (module).OnClose);
288 public virtual Stream GetManifestResourceStream (Type type, String name)
296 if ((ns == null) || (ns == ""))
297 return GetManifestResourceStream (name);
299 return GetManifestResourceStream (ns + "." + name);
302 [MethodImplAttribute (MethodImplOptions.InternalCall)]
303 private extern Type[] GetTypes (bool exportedOnly);
305 public virtual Type[] GetTypes ()
307 return GetTypes (false);
310 public virtual Type[] GetExportedTypes ()
312 return GetTypes (true);
315 public virtual Type GetType (String name, Boolean throwOnError)
317 return GetType (name, throwOnError, false);
320 public virtual Type GetType (String name) {
321 return GetType (name, false, false);
324 [MethodImplAttribute (MethodImplOptions.InternalCall)]
325 internal extern Type InternalGetType (Module module, String name, Boolean throwOnError, Boolean ignoreCase);
327 public Type GetType (string name, bool throwOnError, bool ignoreCase)
330 throw new ArgumentNullException (name);
332 return InternalGetType (null, name, throwOnError, ignoreCase);
335 [MethodImplAttribute (MethodImplOptions.InternalCall)]
336 internal extern static void InternalGetAssemblyName (string assemblyFile, AssemblyName aname);
338 [MethodImplAttribute (MethodImplOptions.InternalCall)]
339 static extern void FillName (Assembly ass, AssemblyName aname);
341 [MonoTODO ("true == not supported")]
342 public virtual AssemblyName GetName (Boolean copiedName)
344 // CodeBase, which is restricted, will be copied into the AssemblyName object so...
345 if (SecurityManager.SecurityEnabled) {
346 GetCodeBase (); // this will ensure the Demand is made
348 return UnprotectedGetName ();
351 public virtual AssemblyName GetName ()
353 return GetName (false);
356 // the security runtime requires access to the assemblyname (e.g. to get the strongname)
357 internal AssemblyName UnprotectedGetName ()
359 AssemblyName aname = new AssemblyName ();
360 FillName (this, aname);
364 public override string ToString ()
366 // note: ToString work without requiring CodeBase (so no checks are needed)
367 AssemblyName aname = new AssemblyName ();
368 FillName (this, aname);
369 return aname.ToString ();
372 public static String CreateQualifiedName (String assemblyName, String typeName)
374 return typeName + ", " + assemblyName;
377 public static Assembly GetAssembly (Type type)
380 return type.Assembly;
381 throw new ArgumentNullException ("type");
385 [MethodImplAttribute (MethodImplOptions.InternalCall)]
386 public static extern Assembly GetEntryAssembly();
388 public Assembly GetSatelliteAssembly (CultureInfo culture)
390 return GetSatelliteAssembly (culture, null);
393 public Assembly GetSatelliteAssembly (CultureInfo culture, Version version)
396 throw new ArgumentException ("culture");
398 AssemblyName aname = GetName (true);
400 aname.Version = version;
402 aname.CultureInfo = culture;
403 aname.Name = aname.Name + ".resources";
407 [MethodImplAttribute (MethodImplOptions.InternalCall)]
408 private extern static Assembly LoadFrom (String assemblyFile, bool refonly);
410 public static Assembly LoadFrom (String assemblyFile)
412 return LoadFrom (assemblyFile, false);
415 public static Assembly LoadFrom (String assemblyFile, Evidence securityEvidence)
417 Assembly a = LoadFrom (assemblyFile, false);
418 if ((a != null) && (securityEvidence != null)) {
419 // merge evidence (i.e. replace defaults with provided evidences)
420 a.Evidence.Merge (securityEvidence);
428 public static Assembly LoadFrom (String assemblyFile, Evidence securityEvidence, byte[] hashValue, AssemblyHashAlgorithm hashAlgorithm)
430 if (assemblyFile == null)
431 throw new ArgumentNullException ("assemblyFile");
432 if (assemblyFile == String.Empty)
433 throw new ArgumentException ("Name can't be the empty string", "assemblyFile");
434 throw new NotImplementedException ();
438 public static Assembly LoadFile (String path, Evidence securityEvidence) {
440 throw new ArgumentNullException ("path");
441 if (path == String.Empty)
442 throw new ArgumentException ("Path can't be empty", "path");
443 // FIXME: Make this do the right thing
444 return LoadFrom (path, securityEvidence);
447 public static Assembly LoadFile (String path) {
448 return LoadFile (path, null);
452 public static Assembly Load (String assemblyString)
454 return AppDomain.CurrentDomain.Load (assemblyString);
457 public static Assembly Load (String assemblyString, Evidence assemblySecurity)
459 return AppDomain.CurrentDomain.Load (assemblyString, assemblySecurity);
462 public static Assembly Load (AssemblyName assemblyRef)
464 return AppDomain.CurrentDomain.Load (assemblyRef);
467 public static Assembly Load (AssemblyName assemblyRef, Evidence assemblySecurity)
469 return AppDomain.CurrentDomain.Load (assemblyRef, assemblySecurity);
472 public static Assembly Load (Byte[] rawAssembly)
474 return AppDomain.CurrentDomain.Load (rawAssembly);
477 public static Assembly Load (Byte[] rawAssembly, Byte[] rawSymbolStore)
479 return AppDomain.CurrentDomain.Load (rawAssembly, rawSymbolStore);
482 public static Assembly Load (Byte[] rawAssembly, Byte[] rawSymbolStore,
483 Evidence securityEvidence)
485 return AppDomain.CurrentDomain.Load (rawAssembly, rawSymbolStore, securityEvidence);
489 public static Assembly ReflectionOnlyLoad (byte[] rawAssembly)
491 return AppDomain.CurrentDomain.Load (rawAssembly, null, null, true);
494 public static Assembly ReflectionOnlyLoad (string assemblyName)
496 return AppDomain.CurrentDomain.Load (assemblyName, null, true);
499 public static Assembly ReflectionOnlyLoadFrom (string assemblyFile)
501 if (assemblyFile == null)
502 throw new ArgumentNullException ("assemblyFile");
504 return LoadFrom (assemblyFile, true);
511 public static Assembly LoadWithPartialName (string partialName)
513 return LoadWithPartialName (partialName, null);
517 public Module LoadModule (string moduleName, byte [] rawModule)
519 throw new NotImplementedException ();
523 public Module LoadModule (string moduleName, byte [] rawModule, byte [] rawSymbolStore)
525 throw new NotImplementedException ();
528 [MethodImplAttribute (MethodImplOptions.InternalCall)]
529 private static extern Assembly load_with_partial_name (string name, Evidence e);
534 public static Assembly LoadWithPartialName (string partialName, Evidence securityEvidence)
536 return LoadWithPartialName (partialName, securityEvidence, true);
540 * LAMESPEC: It is possible for this method to throw exceptions IF the name supplied
541 * is a valid gac name and contains filesystem entry charachters at the end of the name
542 * ie System/// will throw an exception. However ////System will not as that is canocolized
546 // FIXME: LoadWithPartialName must look cache (no CAS) or read from disk (CAS)
547 internal static Assembly LoadWithPartialName (string partialName, Evidence securityEvidence, bool oldBehavior)
550 throw new NotImplementedException ();
552 if (partialName == null)
553 throw new NullReferenceException ();
555 return load_with_partial_name (partialName, securityEvidence);
558 public Object CreateInstance (String typeName)
560 return CreateInstance (typeName, false);
563 public Object CreateInstance (String typeName, Boolean ignoreCase)
565 Type t = GetType (typeName, false, ignoreCase);
570 return Activator.CreateInstance (t);
571 } catch (InvalidOperationException) {
572 throw new ArgumentException ("It is illegal to invoke a method on a Type loaded via ReflectionOnly methods.");
576 public Object CreateInstance (String typeName, Boolean ignoreCase,
577 BindingFlags bindingAttr, Binder binder,
578 Object[] args, CultureInfo culture,
579 Object[] activationAttributes)
581 Type t = GetType (typeName, false, ignoreCase);
586 return Activator.CreateInstance (t, bindingAttr, binder, args, culture, activationAttributes);
587 } catch (InvalidOperationException) {
588 throw new ArgumentException ("It is illegal to invoke a method on a Type loaded via ReflectionOnly methods.");
592 public Module[] GetLoadedModules ()
594 return GetLoadedModules (false);
598 public Module[] GetLoadedModules (bool getResourceModules)
600 // Currently, the two sets of modules are equal
601 return GetModules (getResourceModules);
604 public Module[] GetModules ()
606 return GetModules (false);
609 public Module GetModule (String name)
612 throw new ArgumentNullException ("name");
614 throw new ArgumentException ("Name can't be empty");
616 Module[] modules = GetModules (true);
617 foreach (Module module in modules) {
618 if (module.ScopeName == name)
625 [MethodImplAttribute (MethodImplOptions.InternalCall)]
626 internal extern Module[] GetModulesInternal ();
628 public Module[] GetModules (bool getResourceModules) {
629 Module[] modules = GetModulesInternal ();
631 if (!getResourceModules) {
632 ArrayList result = new ArrayList (modules.Length);
633 foreach (Module m in modules)
634 if (!m.IsResource ())
636 return (Module[])result.ToArray (typeof (Module));
642 [MethodImplAttribute (MethodImplOptions.InternalCall)]
643 internal extern string[] GetNamespaces ();
645 [MethodImplAttribute (MethodImplOptions.InternalCall)]
646 public extern virtual String[] GetManifestResourceNames ();
648 [MethodImplAttribute (MethodImplOptions.InternalCall)]
649 public extern static Assembly GetExecutingAssembly ();
651 [MethodImplAttribute (MethodImplOptions.InternalCall)]
652 public extern static Assembly GetCallingAssembly ();
654 [MethodImplAttribute (MethodImplOptions.InternalCall)]
655 public extern AssemblyName[] GetReferencedAssemblies ();
657 [MethodImplAttribute (MethodImplOptions.InternalCall)]
658 private extern bool GetManifestResourceInfoInternal (String name, ManifestResourceInfo info);
660 public virtual ManifestResourceInfo GetManifestResourceInfo (String resourceName)
662 if (resourceName == null)
663 throw new ArgumentNullException ("resourceName");
664 if (resourceName == "")
665 throw new ArgumentException ("String cannot have zero length.");
666 ManifestResourceInfo result = new ManifestResourceInfo ();
667 bool found = GetManifestResourceInfoInternal (resourceName, result);
674 private class ResourceCloseHandler {
678 public ResourceCloseHandler (Module module) {
679 this.module = module;
682 public void OnClose (object sender, EventArgs e) {
683 // The module dtor will take care of things
689 // The following functions are only for the Mono Debugger.
692 [MethodImplAttribute (MethodImplOptions.InternalCall)]
693 internal static extern MethodBase MonoDebugger_GetMethod (Assembly assembly, int token);
695 [MethodImplAttribute (MethodImplOptions.InternalCall)]
696 internal static extern int MonoDebugger_GetMethodToken (Assembly assembly, MethodBase method);
698 [MethodImplAttribute (MethodImplOptions.InternalCall)]
699 internal static extern Type MonoDebugger_GetLocalTypeFromSignature (Assembly assembly, byte[] signature);
701 [MethodImplAttribute (MethodImplOptions.InternalCall)]
702 internal static extern Type MonoDebugger_GetType (Assembly assembly, int token);
704 [MethodImplAttribute (MethodImplOptions.InternalCall)]
705 internal static extern string MonoDebugger_CheckRuntimeVersion (string filename);
707 [MethodImplAttribute (MethodImplOptions.InternalCall)]
708 internal static extern string MonoDebugger_GetMethodIndex (MethodBase method);
710 [MethodImplAttribute (MethodImplOptions.InternalCall)]
711 internal static extern Type MonoDebugger_MakeArrayType (Type type, int rank);
713 [MethodImplAttribute (MethodImplOptions.InternalCall)]
714 internal static extern int MonoDebugger_GetTypeToken (Type type);
719 public long HostContext {
724 [Obsolete ("Please use Assembly.ManifestModule.GetPEKind() instead - this will be removed before Whidbey ships.")]
725 public ImageFileMachine ImageFileMachine {
727 ImageFileMachine machine;
728 PortableExecutableKinds kind;
729 ModuleHandle handle = ManifestModule.ModuleHandle;
730 handle.GetPEKind (out kind, out machine);
736 public extern Module ManifestModule {
737 [MethodImplAttribute (MethodImplOptions.InternalCall)]
742 [Obsolete ("This method has been deprecated and will be removed before v2.0 RTM is released.")]
743 public extern int MetadataToken {
744 [MethodImplAttribute (MethodImplOptions.InternalCall)]
749 [Obsolete ("Please use Assembly.ManifestModule.GetPEKind() instead - this will be removed before Whidbey ships.")]
750 public PortableExecutableKinds PortableExecutableKinds {
752 ImageFileMachine machine;
753 PortableExecutableKinds kind;
754 ModuleHandle handle = ManifestModule.ModuleHandle;
755 handle.GetPEKind (out kind, out machine);
761 public virtual extern bool ReflectionOnly {
762 [MethodImplAttribute (MethodImplOptions.InternalCall)]
767 // Code Access Security
769 internal void Resolve ()
772 // FIXME: As we (currently) delay the resolution until the first CAS
773 // Demand it's too late to evaluate the Minimum permission set as a
774 // condition to load the assembly into the AppDomain
775 LoadAssemblyPermissions ();
776 _granted = SecurityManager.ResolvePolicy (UnprotectedGetEvidence (),
777 _minimum, _optional, _refuse, out _denied);
780 Console.WriteLine ("*** ASSEMBLY RESOLVE INPUT ***");
781 if (_minimum != null)
782 Console.WriteLine ("Minimum: {0}", _minimum);
783 if (_optional != null)
784 Console.WriteLine ("Optional: {0}", _optional);
786 Console.WriteLine ("Refuse: {0}", _refuse);
787 Console.WriteLine ("*** ASSEMBLY RESOLVE RESULTS ***");
788 Console.WriteLine ("Granted: {0}", _granted);
790 Console.WriteLine ("Denied: {0}", _denied);
791 Console.WriteLine ("*** ASSEMBLY RESOLVE END ***");
795 internal PermissionSet GrantedPermissionSet {
797 if (_granted == null) {
804 internal PermissionSet DeniedPermissionSet {
806 // yes we look for granted, as denied may be null
807 if (_granted == null) {
814 [MethodImplAttribute (MethodImplOptions.InternalCall)]
815 extern internal static bool LoadPermissions (Assembly a,
816 ref IntPtr minimum, ref int minLength,
817 ref IntPtr optional, ref int optLength,
818 ref IntPtr refused, ref int refLength);
820 // Support for SecurityAction.RequestMinimum, RequestOptional and RequestRefuse
821 private void LoadAssemblyPermissions ()
823 IntPtr minimum = IntPtr.Zero, optional = IntPtr.Zero, refused = IntPtr.Zero;
824 int minLength = 0, optLength = 0, refLength = 0;
825 if (LoadPermissions (this, ref minimum, ref minLength, ref optional,
826 ref optLength, ref refused, ref refLength)) {
828 // Note: no need to cache these permission sets as they will only be created once
829 // at assembly resolution time.
831 byte[] data = new byte [minLength];
832 Marshal.Copy (minimum, data, 0, minLength);
833 _minimum = SecurityManager.Decode (data);
836 byte[] data = new byte [optLength];
837 Marshal.Copy (optional, data, 0, optLength);
838 _optional = SecurityManager.Decode (data);
841 byte[] data = new byte [refLength];
842 Marshal.Copy (refused, data, 0, refLength);
843 _refuse = SecurityManager.Decode (data);