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
;
43 namespace System
.Reflection
{
45 internal class ResolveEventHolder
{
46 public event ModuleResolveEventHandler ModuleResolve
;
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
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
{
76 resolve_event_holder
.ModuleResolve
-= value;
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
{
97 return get_code_base ();
101 internal virtual string CopiedCodeBase
{
103 return get_code_base ();
108 public virtual string EscapedCodeBase
{
110 //FIXME: escape characters -> Uri
111 return get_code_base ();
115 public virtual string FullName
{
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
)]
130 public virtual Evidence Evidence
{
132 // if the host (runtime) hasn't provided it's own evidence...
133 if (_evidence
== null) {
134 // ... we will provide our own
136 _evidence
= Evidence
.GetDefaultHostEvidence (this);
143 public bool GlobalAssemblyCache
{
145 return get_global_assembly_cache ();
149 public virtual String Location
{
151 return get_location ();
157 public virtual string ImageRuntimeVersion
{
159 return InternalImageRuntimeVersion ();
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
);
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
);
204 public virtual FileStream
GetFile (String name
)
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
);
218 [MethodImplAttribute (MethodImplOptions
.InternalCall
)]
219 private extern IntPtr
GetManifestResourceInternal (String name
, out int size
, out Module module
);
221 public virtual Stream
GetManifestResourceStream (String name
)
224 throw new ArgumentNullException ("name");
226 throw new ArgumentException ("name cannot have zero length.");
228 ManifestResourceInfo info
= GetManifestResourceInfo (name
);
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
),
237 return new FileStream (filename
, FileMode
.Open
, FileAccess
.Read
);
242 IntPtr data
= GetManifestResourceInternal (name
, out size
, out module
);
243 if (data
== (IntPtr
) 0)
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
);
257 public virtual Stream
GetManifestResourceStream (Type type
, String name
)
265 if ((ns
== null) || (ns
== ""))
266 return GetManifestResourceStream (name
);
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
)
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
);
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
)
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
)
352 throw new ArgumentException ("culture");
354 AssemblyName aname
= GetName (true);
356 aname
.Version
= version
;
358 aname
.CultureInfo
= culture
;
359 aname
.Name
= aname
.Name
+ ".resources";
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
);
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 ();
389 public static Assembly
LoadFile (String path
, Evidence securityEvidence
) {
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);
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
);
441 public static Assembly
ReflectionOnlyLoad (byte[] rawAssembly
)
443 throw new NotImplementedException ();
447 public static Assembly
ReflectionOnlyLoad (string assemblyString
) {
448 throw new NotImplementedException ();
452 public static Assembly
ReflectionOnlyLoadFrom (string assemblyFile
) {
453 throw new NotImplementedException ();
460 public static Assembly
LoadWithPartialName (string partialName
)
462 return LoadWithPartialName (partialName
, null);
466 public Module
LoadModule (string moduleName
, byte [] rawModule
)
468 throw new NotImplementedException ();
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
);
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
502 static Assembly
LoadWithPartialName (string partialName
, Evidence securityEvidence
, bool oldBehavior
)
505 throw new NotImplementedException ();
507 if (partialName
== null)
508 throw new NullReferenceException ();
510 int ci
= partialName
.IndexOf (',');
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
);
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
);
540 return Activator
.CreateInstance (t
, bindingAttr
, binder
, args
, culture
, activationAttributes
);
543 public Module
[] GetLoadedModules ()
545 return GetLoadedModules (false);
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
)
563 throw new ArgumentNullException ("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
)
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 ())
587 return (Module
[])result
.ToArray (typeof (Module
));
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
);
625 private class ResourceCloseHandler
{
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
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
);
661 public long HostContext
{
666 public ImageFileMachine ImageFileMachine
{
668 ImageFileMachine machine
;
669 PortableExecutableKind kind
;
670 ModuleHandle handle
= ManifestModule
.ModuleHandle
;
671 handle
.GetPEKind (out kind
, out machine
);
677 public extern Module ManifestModule
{
678 [MethodImplAttribute (MethodImplOptions
.InternalCall
)]
683 public extern int MetadataToken
{
684 [MethodImplAttribute (MethodImplOptions
.InternalCall
)]
689 public PortableExecutableKind PortableExecutableKind
{
691 ImageFileMachine machine
;
692 PortableExecutableKind kind
;
693 ModuleHandle handle
= ManifestModule
.ModuleHandle
;
694 handle
.GetPEKind (out kind
, out machine
);
699 [MonoTODO ("see ReflectionOnlyLoad")]
701 public virtual bool ReflectionOnly
{
702 get { return false; }
706 // Code Access Security
708 internal void Resolve ()
711 _granted
= SecurityManager
.ResolvePolicy (Evidence
, _minimum
, _optional
,
712 _refuse
, out _denied
);
715 Console
.WriteLine ("Granted: {0}", _granted
);
717 Console
.WriteLine ("Denied: {0}", _denied
);
721 internal PermissionSet GrantedPermissionSet
{
723 if (_granted
== null) {
730 internal PermissionSet DeniedPermissionSet
{
732 // yes we look for granted, as denied may be null
733 if (_granted
== null) {
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
))
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
))
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 ())
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
))
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
)) {
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
)) {
796 return ps
.IsSubsetOf (GrantedPermissionSet
);