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)
166 throw new ArgumentNullException ("info");
168 UnitySerializationHolder.GetAssemblyData (this, info, context);
171 public virtual bool IsDefined (Type attributeType, bool inherit)
173 return MonoCustomAttrs.IsDefined (this, attributeType, inherit);
176 public virtual object [] GetCustomAttributes (bool inherit)
178 return MonoCustomAttrs.GetCustomAttributes (this, inherit);
181 public virtual object [] GetCustomAttributes (Type attributeType, bool inherit)
183 return MonoCustomAttrs.GetCustomAttributes (this, attributeType, inherit);
186 [MethodImplAttribute (MethodImplOptions.InternalCall)]
187 private extern object GetFilesInternal (String name, bool getResourceModules);
189 public virtual FileStream[] GetFiles ()
191 return GetFiles (false);
194 public virtual FileStream [] GetFiles (bool getResourceModules)
196 string[] names = (string[]) GetFilesInternal (null, getResourceModules);
198 return new FileStream [0];
200 FileStream[] res = new FileStream [names.Length];
201 for (int i = 0; i < names.Length; ++i)
202 res [i] = new FileStream (names [i], FileMode.Open, FileAccess.Read);
206 public virtual FileStream GetFile (String name)
209 throw new ArgumentNullException ("name");
210 if (name.Length == 0)
211 throw new ArgumentException ("name");
213 string filename = (string)GetFilesInternal (name, true);
214 if (filename != null)
215 return new FileStream (filename, FileMode.Open, FileAccess.Read);
220 [MethodImplAttribute (MethodImplOptions.InternalCall)]
221 private extern IntPtr GetManifestResourceInternal (String name, out int size, out Module module);
223 public virtual Stream GetManifestResourceStream (String name)
226 throw new ArgumentNullException ("name");
228 throw new ArgumentException ("name cannot have zero length.");
230 ManifestResourceInfo info = GetManifestResourceInfo (name);
234 if (info.ReferencedAssembly != null)
235 return info.ReferencedAssembly.GetManifestResourceStream (name);
236 if ((info.FileName != null) && (info.ResourceLocation == 0)) {
237 string filename = Path.Combine (Path.GetDirectoryName (Location),
239 return new FileStream (filename, FileMode.Open, FileAccess.Read);
244 IntPtr data = GetManifestResourceInternal (name, out size, out module);
245 if (data == (IntPtr) 0)
248 IntPtrStream stream = new IntPtrStream (data, size);
250 * The returned pointer points inside metadata, so
251 * we have to increase the refcount of the module, and decrease
252 * it when the stream is finalized.
254 stream.Closed += new EventHandler (new ResourceCloseHandler (module).OnClose);
259 public virtual Stream GetManifestResourceStream (Type type, String name)
267 if ((ns == null) || (ns == ""))
268 return GetManifestResourceStream (name);
270 return GetManifestResourceStream (ns + "." + name);
273 [MethodImplAttribute (MethodImplOptions.InternalCall)]
274 private extern Type[] GetTypes (bool exportedOnly);
276 public virtual Type[] GetTypes ()
278 return GetTypes (false);
281 public virtual Type[] GetExportedTypes ()
283 return GetTypes (true);
286 public virtual Type GetType (String name, Boolean throwOnError)
288 return GetType (name, throwOnError, false);
291 public virtual Type GetType (String name) {
292 return GetType (name, false, false);
295 [MethodImplAttribute (MethodImplOptions.InternalCall)]
296 internal extern Type InternalGetType (Module module, String name, Boolean throwOnError, Boolean ignoreCase);
298 public Type GetType (string name, bool throwOnError, bool ignoreCase)
301 throw new ArgumentNullException (name);
303 return InternalGetType (null, name, throwOnError, ignoreCase);
306 [MethodImplAttribute (MethodImplOptions.InternalCall)]
307 internal extern static void InternalGetAssemblyName (string assemblyFile, AssemblyName aname);
309 [MethodImplAttribute (MethodImplOptions.InternalCall)]
310 static extern void FillName (Assembly ass, AssemblyName aname);
312 [MonoTODO ("true == not supported")]
313 public virtual AssemblyName GetName (Boolean copiedName)
315 AssemblyName aname = new AssemblyName ();
316 FillName (this, aname);
320 public virtual AssemblyName GetName ()
322 return GetName (false);
325 public override String ToString ()
327 return GetName ().ToString ();
330 public static String CreateQualifiedName (String assemblyName, String typeName)
332 return typeName + ", " + assemblyName;
335 public static Assembly GetAssembly (Type type)
338 return type.Assembly;
339 throw new ArgumentNullException ("type");
343 [MethodImplAttribute (MethodImplOptions.InternalCall)]
344 public static extern Assembly GetEntryAssembly();
346 public Assembly GetSatelliteAssembly (CultureInfo culture)
348 return GetSatelliteAssembly (culture, null);
351 public Assembly GetSatelliteAssembly (CultureInfo culture, Version version)
354 throw new ArgumentException ("culture");
356 AssemblyName aname = GetName (true);
358 aname.Version = version;
360 aname.CultureInfo = culture;
361 aname.Name = aname.Name + ".resources";
365 [MethodImplAttribute (MethodImplOptions.InternalCall)]
366 private extern static Assembly LoadFrom (String assemblyFile, bool refonly);
368 public static Assembly LoadFrom (String assemblyFile)
370 return LoadFrom (assemblyFile, false);
373 public static Assembly LoadFrom (String assemblyFile, Evidence securityEvidence)
375 Assembly a = LoadFrom (assemblyFile, false);
376 if ((a != null) && (securityEvidence != null)) {
377 // merge evidence (i.e. replace defaults with provided evidences)
378 a.Evidence.Merge (securityEvidence);
386 public static Assembly LoadFrom (String assemblyFile, Evidence securityEvidence, byte[] hashValue, AssemblyHashAlgorithm hashAlgorithm)
388 if (assemblyFile == null)
389 throw new ArgumentNullException ("assemblyFile");
390 if (assemblyFile == String.Empty)
391 throw new ArgumentException ("Name can't be the empty string", "assemblyFile");
392 throw new NotImplementedException ();
396 public static Assembly LoadFile (String path, Evidence securityEvidence) {
398 throw new ArgumentNullException ("path");
399 if (path == String.Empty)
400 throw new ArgumentException ("Path can't be empty", "path");
401 // FIXME: Make this do the right thing
402 return LoadFrom (path, securityEvidence);
405 public static Assembly LoadFile (String path) {
406 return LoadFile (path, null);
410 public static Assembly Load (String assemblyString)
412 return AppDomain.CurrentDomain.Load (assemblyString);
415 public static Assembly Load (String assemblyString, Evidence assemblySecurity)
417 return AppDomain.CurrentDomain.Load (assemblyString, assemblySecurity);
420 public static Assembly Load (AssemblyName assemblyRef)
422 return AppDomain.CurrentDomain.Load (assemblyRef);
425 public static Assembly Load (AssemblyName assemblyRef, Evidence assemblySecurity)
427 return AppDomain.CurrentDomain.Load (assemblyRef, assemblySecurity);
430 public static Assembly Load (Byte[] rawAssembly)
432 return AppDomain.CurrentDomain.Load (rawAssembly);
435 public static Assembly Load (Byte[] rawAssembly, Byte[] rawSymbolStore)
437 return AppDomain.CurrentDomain.Load (rawAssembly, rawSymbolStore);
440 public static Assembly Load (Byte[] rawAssembly, Byte[] rawSymbolStore,
441 Evidence securityEvidence)
443 return AppDomain.CurrentDomain.Load (rawAssembly, rawSymbolStore, securityEvidence);
447 public static Assembly ReflectionOnlyLoad (byte[] rawAssembly)
449 return AppDomain.CurrentDomain.Load (rawAssembly, null, null, true);
452 public static Assembly ReflectionOnlyLoad (string assemblyName)
454 return AppDomain.CurrentDomain.Load (assemblyName, null, true);
457 public static Assembly ReflectionOnlyLoadFrom (string assemblyFile)
459 if (assemblyFile == null)
460 throw new ArgumentNullException ("assemblyFile");
462 return LoadFrom (assemblyFile, true);
469 public static Assembly LoadWithPartialName (string partialName)
471 return LoadWithPartialName (partialName, null);
475 public Module LoadModule (string moduleName, byte [] rawModule)
477 throw new NotImplementedException ();
481 public Module LoadModule (string moduleName, byte [] rawModule, byte [] rawSymbolStore)
483 throw new NotImplementedException ();
486 [MethodImplAttribute (MethodImplOptions.InternalCall)]
487 private static extern Assembly load_with_partial_name (string name, Evidence e);
492 public static Assembly LoadWithPartialName (string partialName, Evidence securityEvidence)
494 return LoadWithPartialName (partialName, securityEvidence, true);
498 * LAMESPEC: It is possible for this method to throw exceptions IF the name supplied
499 * is a valid gac name and contains filesystem entry charachters at the end of the name
500 * ie System/// will throw an exception. However ////System will not as that is canocolized
511 static Assembly LoadWithPartialName (string partialName, Evidence securityEvidence, bool oldBehavior)
514 throw new NotImplementedException ();
516 if (partialName == null)
517 throw new NullReferenceException ();
519 int ci = partialName.IndexOf (',');
521 partialName = partialName.Substring (0, ci);
523 return load_with_partial_name (partialName, securityEvidence);
526 public Object CreateInstance (String typeName)
528 return CreateInstance (typeName, false);
531 public Object CreateInstance (String typeName, Boolean ignoreCase)
533 Type t = GetType (typeName, false, ignoreCase);
538 return Activator.CreateInstance (t);
539 } catch (InvalidOperationException) {
540 throw new ArgumentException ("It is illegal to invoke a method on a Type loaded via ReflectionOnly methods.");
544 public Object CreateInstance (String typeName, Boolean ignoreCase,
545 BindingFlags bindingAttr, Binder binder,
546 Object[] args, CultureInfo culture,
547 Object[] activationAttributes)
549 Type t = GetType (typeName, false, ignoreCase);
554 return Activator.CreateInstance (t, bindingAttr, binder, args, culture, activationAttributes);
555 } catch (InvalidOperationException) {
556 throw new ArgumentException ("It is illegal to invoke a method on a Type loaded via ReflectionOnly methods.");
560 public Module[] GetLoadedModules ()
562 return GetLoadedModules (false);
566 public Module[] GetLoadedModules (bool getResourceModules)
568 // Currently, the two sets of modules are equal
569 return GetModules (getResourceModules);
572 public Module[] GetModules ()
574 return GetModules (false);
577 public Module GetModule (String name)
580 throw new ArgumentNullException ("name");
582 throw new ArgumentException ("Name can't be empty");
584 Module[] modules = GetModules (true);
585 foreach (Module module in modules) {
586 if (module.ScopeName == name)
593 [MethodImplAttribute (MethodImplOptions.InternalCall)]
594 internal extern Module[] GetModulesInternal ();
596 public Module[] GetModules (bool getResourceModules) {
597 Module[] modules = GetModulesInternal ();
599 if (!getResourceModules) {
600 ArrayList result = new ArrayList (modules.Length);
601 foreach (Module m in modules)
602 if (!m.IsResource ())
604 return (Module[])result.ToArray (typeof (Module));
610 [MethodImplAttribute (MethodImplOptions.InternalCall)]
611 internal extern string[] GetNamespaces ();
613 [MethodImplAttribute (MethodImplOptions.InternalCall)]
614 public extern virtual String[] GetManifestResourceNames ();
616 [MethodImplAttribute (MethodImplOptions.InternalCall)]
617 public extern static Assembly GetExecutingAssembly ();
619 [MethodImplAttribute (MethodImplOptions.InternalCall)]
620 public extern static Assembly GetCallingAssembly ();
622 [MethodImplAttribute (MethodImplOptions.InternalCall)]
623 public extern AssemblyName[] GetReferencedAssemblies ();
625 [MethodImplAttribute (MethodImplOptions.InternalCall)]
626 private extern bool GetManifestResourceInfoInternal (String name, ManifestResourceInfo info);
628 public virtual ManifestResourceInfo GetManifestResourceInfo (String resourceName)
630 if (resourceName == null)
631 throw new ArgumentNullException ("resourceName");
632 if (resourceName == "")
633 throw new ArgumentException ("String cannot have zero length.");
634 ManifestResourceInfo result = new ManifestResourceInfo ();
635 bool found = GetManifestResourceInfoInternal (resourceName, result);
642 private class ResourceCloseHandler {
646 public ResourceCloseHandler (Module module) {
647 this.module = module;
650 public void OnClose (object sender, EventArgs e) {
651 // The module dtor will take care of things
657 // The following functions are only for the Mono Debugger.
660 [MethodImplAttribute (MethodImplOptions.InternalCall)]
661 internal static extern MethodBase MonoDebugger_GetMethod (Assembly assembly, int token);
663 [MethodImplAttribute (MethodImplOptions.InternalCall)]
664 internal static extern int MonoDebugger_GetMethodToken (Assembly assembly, MethodBase method);
666 [MethodImplAttribute (MethodImplOptions.InternalCall)]
667 internal static extern Type MonoDebugger_GetLocalTypeFromSignature (Assembly assembly, byte[] signature);
669 [MethodImplAttribute (MethodImplOptions.InternalCall)]
670 internal static extern Type MonoDebugger_GetType (Assembly assembly, int token);
672 [MethodImplAttribute (MethodImplOptions.InternalCall)]
673 internal static extern string MonoDebugger_CheckRuntimeVersion (string filename);
675 [MethodImplAttribute (MethodImplOptions.InternalCall)]
676 internal static extern string MonoDebugger_GetMethodIndex (MethodBase method);
678 [MethodImplAttribute (MethodImplOptions.InternalCall)]
679 internal static extern Type MonoDebugger_MakeArrayType (Type type, int rank);
681 [MethodImplAttribute (MethodImplOptions.InternalCall)]
682 internal static extern int MonoDebugger_GetTypeToken (Type type);
687 public long HostContext {
692 public ImageFileMachine ImageFileMachine {
694 ImageFileMachine machine;
695 PortableExecutableKind kind;
696 ModuleHandle handle = ManifestModule.ModuleHandle;
697 handle.GetPEKind (out kind, out machine);
703 public extern Module ManifestModule {
704 [MethodImplAttribute (MethodImplOptions.InternalCall)]
709 public extern int MetadataToken {
710 [MethodImplAttribute (MethodImplOptions.InternalCall)]
715 public PortableExecutableKind PortableExecutableKind {
717 ImageFileMachine machine;
718 PortableExecutableKind kind;
719 ModuleHandle handle = ManifestModule.ModuleHandle;
720 handle.GetPEKind (out kind, out machine);
726 public virtual extern bool ReflectionOnly {
727 [MethodImplAttribute (MethodImplOptions.InternalCall)]
732 // Code Access Security
734 internal void Resolve ()
737 // FIXME: As we (currently) delay the resolution until the first CAS
738 // Demand it's too late to evaluate the Minimum permission set as a
739 // condition to load the assembly into the AppDomain
740 LoadAssemblyPermissions ();
741 _granted = SecurityManager.ResolvePolicy (Evidence, _minimum, _optional,
742 _refuse, out _denied);
745 Console.WriteLine ("*** ASSEMBLY RESOLVE INPUT ***");
746 if (_minimum != null)
747 Console.WriteLine ("Minimum: {0}", _minimum);
748 if (_optional != null)
749 Console.WriteLine ("Optional: {0}", _optional);
751 Console.WriteLine ("Refuse: {0}", _refuse);
752 Console.WriteLine ("*** ASSEMBLY RESOLVE RESULTS ***");
753 Console.WriteLine ("Granted: {0}", _granted);
755 Console.WriteLine ("Denied: {0}", _denied);
756 Console.WriteLine ("*** ASSEMBLY RESOLVE END ***");
760 internal PermissionSet GrantedPermissionSet {
762 if (_granted == null) {
769 internal PermissionSet DeniedPermissionSet {
771 // yes we look for granted, as denied may be null
772 if (_granted == null) {
779 [MethodImplAttribute (MethodImplOptions.InternalCall)]
780 extern internal static bool LoadPermissions (Assembly a,
781 ref IntPtr minimum, ref int minLength,
782 ref IntPtr optional, ref int optLength,
783 ref IntPtr refused, ref int refLength);
785 // Support for SecurityAction.RequestMinimum, RequestOptional and RequestRefuse
786 private void LoadAssemblyPermissions ()
788 IntPtr minimum = IntPtr.Zero, optional = IntPtr.Zero, refused = IntPtr.Zero;
789 int minLength = 0, optLength = 0, refLength = 0;
790 if (LoadPermissions (this, ref minimum, ref minLength, ref optional,
791 ref optLength, ref refused, ref refLength)) {
793 // Note: no need to cache these permission sets as they will only be created once
794 // at assembly resolution time.
796 byte[] data = new byte [minLength];
797 Marshal.Copy (minimum, data, 0, minLength);
798 _minimum = SecurityManager.Decode (data);
801 byte[] data = new byte [optLength];
802 Marshal.Copy (optional, data, 0, optLength);
803 _optional = SecurityManager.Decode (data);
806 byte[] data = new byte [refLength];
807 Marshal.Copy (refused, data, 0, refLength);
808 _refuse = SecurityManager.Decode (data);