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 {
48 [ClassInterface(ClassInterfaceType.None)]
49 public class Assembly : System.Reflection.ICustomAttributeProvider,
50 System.Security.IEvidenceFactory, System.Runtime.Serialization.ISerializable {
51 internal class ResolveEventHolder {
52 public event ModuleResolveEventHandler ModuleResolve;
55 // Note: changes to fields must be reflected in _MonoReflectionAssembly struct (object-internals.h)
56 private IntPtr _mono_assembly;
58 private ResolveEventHolder resolve_event_holder;
59 private Evidence _evidence;
60 internal PermissionSet _minimum; // for SecurityAction.RequestMinimum
61 internal PermissionSet _optional; // for SecurityAction.RequestOptional
62 internal PermissionSet _refuse; // for SecurityAction.RequestRefuse
63 private PermissionSet _granted; // for the resolved assembly granted permissions
64 private PermissionSet _denied; // for the resolved assembly denied permissions
68 resolve_event_holder = new ResolveEventHolder ();
72 // We can't store the event directly in this class, since the
73 // compiler would silently insert the fields before _mono_assembly
75 public event ModuleResolveEventHandler ModuleResolve {
77 resolve_event_holder.ModuleResolve += value;
80 resolve_event_holder.ModuleResolve -= value;
84 [MethodImplAttribute (MethodImplOptions.InternalCall)]
85 private extern string get_code_base ();
87 [MethodImplAttribute (MethodImplOptions.InternalCall)]
88 private extern string get_location ();
90 [MethodImplAttribute (MethodImplOptions.InternalCall)]
91 private extern string InternalImageRuntimeVersion ();
93 [MethodImplAttribute (MethodImplOptions.InternalCall)]
94 private extern bool get_global_assembly_cache ();
96 public virtual string CodeBase {
98 return get_code_base ();
102 internal virtual string CopiedCodeBase {
104 return get_code_base ();
108 public virtual string EscapedCodeBase {
110 return Uri.EscapeString (get_code_base (), false, true, true);
114 public virtual string FullName {
117 // FIXME: This is wrong, but it gets us going
118 // in the compiler for now
120 return GetName (false).ToString ();
124 public virtual extern MethodInfo EntryPoint {
125 [MethodImplAttribute (MethodImplOptions.InternalCall)]
129 public virtual Evidence Evidence {
131 // if the host (runtime) hasn't provided it's own evidence...
132 if (_evidence == null) {
133 // ... we will provide our own
135 _evidence = Evidence.GetDefaultHostEvidence (this);
142 public bool GlobalAssemblyCache {
144 return get_global_assembly_cache ();
148 public virtual String Location {
150 return get_location ();
156 public virtual string ImageRuntimeVersion {
158 return InternalImageRuntimeVersion ();
163 public virtual void GetObjectData (SerializationInfo info, StreamingContext context)
165 UnitySerializationHolder.GetAssemblyData (this, info, context);
168 public virtual bool IsDefined (Type attributeType, bool inherit)
170 return MonoCustomAttrs.IsDefined (this, attributeType, inherit);
173 public virtual object [] GetCustomAttributes (bool inherit)
175 return MonoCustomAttrs.GetCustomAttributes (this, inherit);
178 public virtual object [] GetCustomAttributes (Type attributeType, bool inherit)
180 return MonoCustomAttrs.GetCustomAttributes (this, attributeType, inherit);
183 [MethodImplAttribute (MethodImplOptions.InternalCall)]
184 private extern object GetFilesInternal (String name, bool getResourceModules);
186 public virtual FileStream[] GetFiles ()
188 return GetFiles (false);
191 public virtual FileStream [] GetFiles (bool getResourceModules)
193 string[] names = (string[]) GetFilesInternal (null, getResourceModules);
195 return new FileStream [0];
197 FileStream[] res = new FileStream [names.Length];
198 for (int i = 0; i < names.Length; ++i)
199 res [i] = new FileStream (names [i], FileMode.Open, FileAccess.Read);
203 public virtual FileStream GetFile (String name)
206 throw new ArgumentNullException ("name");
207 if (name.Length == 0)
208 throw new ArgumentException ("name");
210 string filename = (string)GetFilesInternal (name, true);
211 if (filename != null)
212 return new FileStream (filename, FileMode.Open, FileAccess.Read);
217 [MethodImplAttribute (MethodImplOptions.InternalCall)]
218 private extern IntPtr GetManifestResourceInternal (String name, out int size, out Module module);
220 public virtual Stream GetManifestResourceStream (String name)
223 throw new ArgumentNullException ("name");
225 throw new ArgumentException ("name cannot have zero length.");
227 ManifestResourceInfo info = GetManifestResourceInfo (name);
231 if (info.ReferencedAssembly != null)
232 return info.ReferencedAssembly.GetManifestResourceStream (name);
233 if ((info.FileName != null) && (info.ResourceLocation == 0)) {
234 string filename = Path.Combine (Path.GetDirectoryName (Location),
236 return new FileStream (filename, FileMode.Open, FileAccess.Read);
241 IntPtr data = GetManifestResourceInternal (name, out size, out module);
242 if (data == (IntPtr) 0)
245 IntPtrStream stream = new IntPtrStream (data, size);
247 * The returned pointer points inside metadata, so
248 * we have to increase the refcount of the module, and decrease
249 * it when the stream is finalized.
251 stream.Closed += new EventHandler (new ResourceCloseHandler (module).OnClose);
256 public virtual Stream GetManifestResourceStream (Type type, String name)
264 if ((ns == null) || (ns == ""))
265 return GetManifestResourceStream (name);
267 return GetManifestResourceStream (ns + "." + name);
270 [MethodImplAttribute (MethodImplOptions.InternalCall)]
271 private extern Type[] GetTypes (bool exportedOnly);
273 public virtual Type[] GetTypes ()
275 return GetTypes (false);
278 public virtual Type[] GetExportedTypes ()
280 return GetTypes (true);
283 public virtual Type GetType (String name, Boolean throwOnError)
285 return GetType (name, throwOnError, false);
288 public virtual Type GetType (String name) {
289 return GetType (name, false, false);
292 [MethodImplAttribute (MethodImplOptions.InternalCall)]
293 internal extern Type InternalGetType (Module module, String name, Boolean throwOnError, Boolean ignoreCase);
295 public Type GetType (string name, bool throwOnError, bool ignoreCase)
298 throw new ArgumentNullException (name);
300 return InternalGetType (null, name, throwOnError, ignoreCase);
303 [MethodImplAttribute (MethodImplOptions.InternalCall)]
304 internal extern static void InternalGetAssemblyName (string assemblyFile, AssemblyName aname);
306 [MethodImplAttribute (MethodImplOptions.InternalCall)]
307 static extern void FillName (Assembly ass, AssemblyName aname);
309 [MonoTODO ("true == not supported")]
310 public virtual AssemblyName GetName (Boolean copiedName)
312 AssemblyName aname = new AssemblyName ();
313 FillName (this, aname);
317 public virtual AssemblyName GetName ()
319 return GetName (false);
322 public override String ToString ()
324 return GetName ().ToString ();
327 public static String CreateQualifiedName (String assemblyName, String typeName)
329 return typeName + ", " + assemblyName;
332 public static Assembly GetAssembly (Type type)
335 return type.Assembly;
336 throw new ArgumentNullException ("type");
340 [MethodImplAttribute (MethodImplOptions.InternalCall)]
341 public static extern Assembly GetEntryAssembly();
343 public Assembly GetSatelliteAssembly (CultureInfo culture)
345 return GetSatelliteAssembly (culture, null);
348 public Assembly GetSatelliteAssembly (CultureInfo culture, Version version)
351 throw new ArgumentException ("culture");
353 AssemblyName aname = GetName (true);
355 aname.Version = version;
357 aname.CultureInfo = culture;
358 aname.Name = aname.Name + ".resources";
362 [MethodImplAttribute (MethodImplOptions.InternalCall)]
363 private extern static Assembly LoadFrom (String assemblyFile, bool refonly);
365 public static Assembly LoadFrom (String assemblyFile)
367 return LoadFrom (assemblyFile, false);
370 public static Assembly LoadFrom (String assemblyFile, Evidence securityEvidence)
372 Assembly a = LoadFrom (assemblyFile, false);
373 if ((a != null) && (securityEvidence != null)) {
374 // merge evidence (i.e. replace defaults with provided evidences)
375 a.Evidence.Merge (securityEvidence);
383 public static Assembly LoadFrom (String assemblyFile, Evidence securityEvidence, byte[] hashValue, AssemblyHashAlgorithm hashAlgorithm)
385 if (assemblyFile == null)
386 throw new ArgumentNullException ("assemblyFile");
387 if (assemblyFile == String.Empty)
388 throw new ArgumentException ("Name can't be the empty string", "assemblyFile");
389 throw new NotImplementedException ();
393 public static Assembly LoadFile (String path, Evidence securityEvidence) {
395 throw new ArgumentNullException ("path");
396 if (path == String.Empty)
397 throw new ArgumentException ("Path can't be empty", "path");
398 // FIXME: Make this do the right thing
399 return LoadFrom (path, securityEvidence);
402 public static Assembly LoadFile (String path) {
403 return LoadFile (path, null);
407 public static Assembly Load (String assemblyString)
409 return AppDomain.CurrentDomain.Load (assemblyString);
412 public static Assembly Load (String assemblyString, Evidence assemblySecurity)
414 return AppDomain.CurrentDomain.Load (assemblyString, assemblySecurity);
417 public static Assembly Load (AssemblyName assemblyRef)
419 return AppDomain.CurrentDomain.Load (assemblyRef);
422 public static Assembly Load (AssemblyName assemblyRef, Evidence assemblySecurity)
424 return AppDomain.CurrentDomain.Load (assemblyRef, assemblySecurity);
427 public static Assembly Load (Byte[] rawAssembly)
429 return AppDomain.CurrentDomain.Load (rawAssembly);
432 public static Assembly Load (Byte[] rawAssembly, Byte[] rawSymbolStore)
434 return AppDomain.CurrentDomain.Load (rawAssembly, rawSymbolStore);
437 public static Assembly Load (Byte[] rawAssembly, Byte[] rawSymbolStore,
438 Evidence securityEvidence)
440 return AppDomain.CurrentDomain.Load (rawAssembly, rawSymbolStore, securityEvidence);
444 public static Assembly ReflectionOnlyLoad (byte[] rawAssembly)
446 return AppDomain.CurrentDomain.Load (rawAssembly, null, null, true);
449 public static Assembly ReflectionOnlyLoad (string assemblyName)
451 return AppDomain.CurrentDomain.Load (assemblyName, null, true);
454 public static Assembly ReflectionOnlyLoadFrom (string assemblyFile)
456 if (assemblyFile == null)
457 throw new ArgumentNullException ("assemblyFile");
459 return LoadFrom (assemblyFile, true);
466 public static Assembly LoadWithPartialName (string partialName)
468 return LoadWithPartialName (partialName, null);
472 public Module LoadModule (string moduleName, byte [] rawModule)
474 throw new NotImplementedException ();
478 public Module LoadModule (string moduleName, byte [] rawModule, byte [] rawSymbolStore)
480 throw new NotImplementedException ();
483 [MethodImplAttribute (MethodImplOptions.InternalCall)]
484 private static extern Assembly load_with_partial_name (string name, Evidence e);
489 public static Assembly LoadWithPartialName (string partialName, Evidence securityEvidence)
491 return LoadWithPartialName (partialName, securityEvidence, true);
495 * LAMESPEC: It is possible for this method to throw exceptions IF the name supplied
496 * is a valid gac name and contains filesystem entry charachters at the end of the name
497 * ie System/// will throw an exception. However ////System will not as that is canocolized
508 static Assembly LoadWithPartialName (string partialName, Evidence securityEvidence, bool oldBehavior)
511 throw new NotImplementedException ();
513 if (partialName == null)
514 throw new NullReferenceException ();
516 int ci = partialName.IndexOf (',');
518 partialName = partialName.Substring (0, ci);
520 return load_with_partial_name (partialName, securityEvidence);
523 public Object CreateInstance (String typeName)
525 return CreateInstance (typeName, false);
528 public Object CreateInstance (String typeName, Boolean ignoreCase)
530 Type t = GetType (typeName, false, ignoreCase);
535 return Activator.CreateInstance (t);
536 } catch (InvalidOperationException) {
537 throw new ArgumentException ("It is illegal to invoke a method on a Type loaded via ReflectionOnly methods.");
541 public Object CreateInstance (String typeName, Boolean ignoreCase,
542 BindingFlags bindingAttr, Binder binder,
543 Object[] args, CultureInfo culture,
544 Object[] activationAttributes)
546 Type t = GetType (typeName, false, ignoreCase);
551 return Activator.CreateInstance (t, bindingAttr, binder, args, culture, activationAttributes);
552 } catch (InvalidOperationException) {
553 throw new ArgumentException ("It is illegal to invoke a method on a Type loaded via ReflectionOnly methods.");
557 public Module[] GetLoadedModules ()
559 return GetLoadedModules (false);
563 public Module[] GetLoadedModules (bool getResourceModules)
565 // Currently, the two sets of modules are equal
566 return GetModules (getResourceModules);
569 public Module[] GetModules ()
571 return GetModules (false);
574 public Module GetModule (String name)
577 throw new ArgumentNullException ("name");
579 throw new ArgumentException ("Name can't be empty");
581 Module[] modules = GetModules (true);
582 foreach (Module module in modules) {
583 if (module.ScopeName == name)
590 [MethodImplAttribute (MethodImplOptions.InternalCall)]
591 internal extern Module[] GetModulesInternal ();
593 public Module[] GetModules (bool getResourceModules) {
594 Module[] modules = GetModulesInternal ();
596 if (!getResourceModules) {
597 ArrayList result = new ArrayList (modules.Length);
598 foreach (Module m in modules)
599 if (!m.IsResource ())
601 return (Module[])result.ToArray (typeof (Module));
607 [MethodImplAttribute (MethodImplOptions.InternalCall)]
608 internal extern string[] GetNamespaces ();
610 [MethodImplAttribute (MethodImplOptions.InternalCall)]
611 public extern virtual String[] GetManifestResourceNames ();
613 [MethodImplAttribute (MethodImplOptions.InternalCall)]
614 public extern static Assembly GetExecutingAssembly ();
616 [MethodImplAttribute (MethodImplOptions.InternalCall)]
617 public extern static Assembly GetCallingAssembly ();
619 [MethodImplAttribute (MethodImplOptions.InternalCall)]
620 public extern AssemblyName[] GetReferencedAssemblies ();
622 [MethodImplAttribute (MethodImplOptions.InternalCall)]
623 private extern bool GetManifestResourceInfoInternal (String name, ManifestResourceInfo info);
625 public virtual ManifestResourceInfo GetManifestResourceInfo (String resourceName)
627 if (resourceName == null)
628 throw new ArgumentNullException ("resourceName");
629 if (resourceName == "")
630 throw new ArgumentException ("String cannot have zero length.");
631 ManifestResourceInfo result = new ManifestResourceInfo ();
632 bool found = GetManifestResourceInfoInternal (resourceName, result);
639 private class ResourceCloseHandler {
643 public ResourceCloseHandler (Module module) {
644 this.module = module;
647 public void OnClose (object sender, EventArgs e) {
648 // The module dtor will take care of things
654 // The following functions are only for the Mono Debugger.
657 [MethodImplAttribute (MethodImplOptions.InternalCall)]
658 internal static extern MethodBase MonoDebugger_GetMethod (Assembly assembly, int token);
660 [MethodImplAttribute (MethodImplOptions.InternalCall)]
661 internal static extern int MonoDebugger_GetMethodToken (Assembly assembly, MethodBase method);
663 [MethodImplAttribute (MethodImplOptions.InternalCall)]
664 internal static extern Type MonoDebugger_GetLocalTypeFromSignature (Assembly assembly, byte[] signature);
666 [MethodImplAttribute (MethodImplOptions.InternalCall)]
667 internal static extern Type MonoDebugger_GetType (Assembly assembly, int token);
669 [MethodImplAttribute (MethodImplOptions.InternalCall)]
670 internal static extern string MonoDebugger_CheckRuntimeVersion (string filename);
672 [MethodImplAttribute (MethodImplOptions.InternalCall)]
673 internal static extern string MonoDebugger_GetMethodIndex (MethodBase method);
675 [MethodImplAttribute (MethodImplOptions.InternalCall)]
676 internal static extern Type MonoDebugger_MakeArrayType (Type type, int rank);
678 [MethodImplAttribute (MethodImplOptions.InternalCall)]
679 internal static extern int MonoDebugger_GetTypeToken (Type type);
684 public long HostContext {
689 public ImageFileMachine ImageFileMachine {
691 ImageFileMachine machine;
692 PortableExecutableKind kind;
693 ModuleHandle handle = ManifestModule.ModuleHandle;
694 handle.GetPEKind (out kind, out machine);
700 public extern Module ManifestModule {
701 [MethodImplAttribute (MethodImplOptions.InternalCall)]
706 public extern int MetadataToken {
707 [MethodImplAttribute (MethodImplOptions.InternalCall)]
712 public PortableExecutableKind PortableExecutableKind {
714 ImageFileMachine machine;
715 PortableExecutableKind kind;
716 ModuleHandle handle = ManifestModule.ModuleHandle;
717 handle.GetPEKind (out kind, out machine);
723 public virtual extern bool ReflectionOnly {
724 [MethodImplAttribute (MethodImplOptions.InternalCall)]
729 // Code Access Security
731 internal void Resolve ()
734 // FIXME: As we (currently) delay the resolution until the first CAS
735 // Demand it's too late to evaluate the Minimum permission set as a
736 // condition to load the assembly into the AppDomain
737 LoadAssemblyPermissions ();
738 _granted = SecurityManager.ResolvePolicy (Evidence, _minimum, _optional,
739 _refuse, out _denied);
742 Console.WriteLine ("*** ASSEMBLY RESOLVE INPUT ***");
743 if (_minimum != null)
744 Console.WriteLine ("Minimum: {0}", _minimum);
745 if (_optional != null)
746 Console.WriteLine ("Optional: {0}", _optional);
748 Console.WriteLine ("Refuse: {0}", _refuse);
749 Console.WriteLine ("*** ASSEMBLY RESOLVE RESULTS ***");
750 Console.WriteLine ("Granted: {0}", _granted);
752 Console.WriteLine ("Denied: {0}", _denied);
753 Console.WriteLine ("*** ASSEMBLY RESOLVE END ***");
757 internal PermissionSet GrantedPermissionSet {
759 if (_granted == null) {
766 internal PermissionSet DeniedPermissionSet {
768 // yes we look for granted, as denied may be null
769 if (_granted == null) {
776 [MethodImplAttribute (MethodImplOptions.InternalCall)]
777 extern internal static bool LoadPermissions (Assembly a,
778 ref IntPtr minimum, ref int minLength,
779 ref IntPtr optional, ref int optLength,
780 ref IntPtr refused, ref int refLength);
782 // Support for SecurityAction.RequestMinimum, RequestOptional and RequestRefuse
783 private void LoadAssemblyPermissions ()
785 IntPtr minimum = IntPtr.Zero, optional = IntPtr.Zero, refused = IntPtr.Zero;
786 int minLength = 0, optLength = 0, refLength = 0;
787 if (LoadPermissions (this, ref minimum, ref minLength, ref optional,
788 ref optLength, ref refused, ref refLength)) {
790 // Note: no need to cache these permission sets as they will only be created once
791 // at assembly resolution time.
793 byte[] data = new byte [minLength];
794 Marshal.Copy (minimum, data, 0, minLength);
795 _minimum = SecurityManager.Decode (data);
798 byte[] data = new byte [optLength];
799 Marshal.Copy (optional, data, 0, optLength);
800 _optional = SecurityManager.Decode (data);
803 byte[] data = new byte [refLength];
804 Marshal.Copy (refused, data, 0, refLength);
805 _refuse = SecurityManager.Decode (data);