2005-06-05 Peter Bartok <pbartok@novell.com>
[mono.git] / mcs / class / corlib / System.Reflection / Assembly.cs
1 //
2 // System.Reflection/Assembly.cs
3 //
4 // Author:
5 //   Paolo Molaro (lupus@ximian.com)
6 //
7 // (C) 2001 Ximian, Inc.  http://www.ximian.com
8 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
9 //
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:
17 // 
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
20 // 
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.
28 //
29
30 using System;
31 using System.Security;
32 using System.Security.Policy;
33 using System.Security.Permissions;
34 using System.Runtime.Serialization;
35 using System.Reflection.Emit;
36 using System.IO;
37 using System.Globalization;
38 using System.Runtime.CompilerServices;
39 using System.Runtime.InteropServices;
40 using System.Collections;
41 using System.Configuration.Assemblies;
42
43 using Mono.Security;
44
45 namespace System.Reflection {
46
47         [Serializable]
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;
53                 }
54
55                 // Note: changes to fields must be reflected in _MonoReflectionAssembly struct (object-internals.h)
56                 private IntPtr _mono_assembly;
57
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
65                 private bool fromByteArray;
66                 
67                 internal Assembly () 
68                 {
69                         resolve_event_holder = new ResolveEventHolder ();
70                 }
71
72                 //
73                 // We can't store the event directly in this class, since the
74                 // compiler would silently insert the fields before _mono_assembly
75                 //
76                 public event ModuleResolveEventHandler ModuleResolve {
77                         [SecurityPermission (SecurityAction.LinkDemand, ControlAppDomain = true)]
78                         add {
79                                 resolve_event_holder.ModuleResolve += value;
80                         }
81                         [SecurityPermission (SecurityAction.LinkDemand, ControlAppDomain = true)]
82                         remove {
83                                 resolve_event_holder.ModuleResolve -= value;
84                         }
85                 }
86
87                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
88                 private extern string get_code_base ();
89
90                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
91                 private extern string get_location ();
92
93                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
94                 private extern string InternalImageRuntimeVersion ();
95
96                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
97                 private extern bool get_global_assembly_cache ();
98
99                 // SECURITY: this should be the only caller to icall get_code_base
100                 private string GetCodeBase ()
101                 {
102                         string cb = get_code_base ();
103                         if (SecurityManager.SecurityEnabled) {
104                                 // we cannot divulge local file informations
105                                 if (String.Compare ("FILE://", 0, cb, 0, 7, true, CultureInfo.InvariantCulture) == 0) {
106                                         string file = cb.Substring (7);
107                                         new FileIOPermission (FileIOPermissionAccess.PathDiscovery, file).Demand ();
108                                 }
109                         }
110                         return cb;
111                 }
112
113                 public virtual string CodeBase {
114                         get { return GetCodeBase (); }
115                 }
116
117                 public virtual string EscapedCodeBase {
118                         get { return Uri.EscapeString (GetCodeBase (), false, true, true); }
119                 }
120
121                 public virtual string FullName {
122                         get {
123                                 //
124                                 // FIXME: This is wrong, but it gets us going
125                                 // in the compiler for now
126                                 //
127                                 return ToString ();
128                         }
129                 }
130
131                 public virtual extern MethodInfo EntryPoint {
132                         [MethodImplAttribute (MethodImplOptions.InternalCall)]
133                         get;
134                 }
135
136                 public virtual Evidence Evidence {
137                         [SecurityPermission (SecurityAction.Demand, ControlEvidence = true)]
138                         get { return UnprotectedGetEvidence (); }
139                 }
140
141                 // note: the security runtime requires evidences but may be unable to do so...
142                 internal Evidence UnprotectedGetEvidence ()
143                 {
144                         // if the host (runtime) hasn't provided it's own evidence...
145                         if (_evidence == null) {
146                                 // ... we will provide our own
147                                 lock (this) {
148                                         _evidence = Evidence.GetDefaultHostEvidence (this);
149                                 }
150                         }
151                         return _evidence;
152                 }
153
154                 public bool GlobalAssemblyCache {
155                         get {
156                                 return get_global_assembly_cache ();
157                         }
158                 }
159
160                 internal bool FromByteArray {
161                         set { fromByteArray = true; }
162                 }
163
164                 public virtual String Location {
165                         get {
166                                 if (fromByteArray)
167                                         return String.Empty;
168
169                                 string loc = get_location ();
170                                 if ((loc != String.Empty) && SecurityManager.SecurityEnabled) {
171                                         // we cannot divulge local file informations
172                                         new FileIOPermission (FileIOPermissionAccess.PathDiscovery, loc).Demand ();
173                                 }
174                                 return loc;
175                         }
176                 }
177
178 #if NET_1_1
179                 [ComVisible (false)]
180                 public virtual string ImageRuntimeVersion {
181                         get {
182                                 return InternalImageRuntimeVersion ();
183                         }
184                 }
185 #endif
186
187                 [SecurityPermission (SecurityAction.LinkDemand, SerializationFormatter = true)]
188                 public virtual void GetObjectData (SerializationInfo info, StreamingContext context)
189                 {
190                         if (info == null)
191                                 throw new ArgumentNullException ("info");
192
193                         UnitySerializationHolder.GetAssemblyData (this, info, context);
194                 }
195
196                 public virtual bool IsDefined (Type attributeType, bool inherit)
197                 {
198                         return MonoCustomAttrs.IsDefined (this, attributeType, inherit);
199                 }
200
201                 public virtual object [] GetCustomAttributes (bool inherit)
202                 {
203                         return MonoCustomAttrs.GetCustomAttributes (this, inherit);
204                 }
205
206                 public virtual object [] GetCustomAttributes (Type attributeType, bool inherit)
207                 {
208                         return MonoCustomAttrs.GetCustomAttributes (this, attributeType, inherit);
209                 }
210
211                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
212                 private extern object GetFilesInternal (String name, bool getResourceModules);
213
214                 public virtual FileStream[] GetFiles ()
215                 {
216                         return GetFiles (false);
217                 }
218
219                 public virtual FileStream [] GetFiles (bool getResourceModules)
220                 {
221                         string[] names = (string[]) GetFilesInternal (null, getResourceModules);
222                         if (names == null)
223                                 return new FileStream [0];
224
225                         FileStream[] res = new FileStream [names.Length];
226                         for (int i = 0; i < names.Length; ++i)
227                                 res [i] = new FileStream (names [i], FileMode.Open, FileAccess.Read);
228                         return res;
229                 }
230
231                 public virtual FileStream GetFile (String name)
232                 {
233                         if (name == null)
234                                 throw new ArgumentNullException ("name");
235                         if (name.Length == 0)
236                                 throw new ArgumentException ("name");
237
238                         string filename = (string)GetFilesInternal (name, true);
239                         if (filename != null)
240                                 return new FileStream (filename, FileMode.Open, FileAccess.Read);
241                         else
242                                 return null;
243                 }
244
245                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
246                 private extern IntPtr GetManifestResourceInternal (String name, out int size, out Module module);
247
248                 public virtual Stream GetManifestResourceStream (String name)
249                 {
250                         if (name == null)
251                                 throw new ArgumentNullException ("name");
252                         if (name == "")
253                                 throw new ArgumentException ("name cannot have zero length.");
254
255                         ManifestResourceInfo info = GetManifestResourceInfo (name);
256                         if (info == null)
257                                 return null;
258
259                         if (info.ReferencedAssembly != null)
260                                 return info.ReferencedAssembly.GetManifestResourceStream (name);
261                         if ((info.FileName != null) && (info.ResourceLocation == 0)) {
262                                 string filename = Path.Combine (Path.GetDirectoryName (Location),
263                                                                                         info.FileName);
264                                 return new FileStream (filename, FileMode.Open, FileAccess.Read);
265                         }
266
267                         int size;
268                         Module module;
269                         IntPtr data = GetManifestResourceInternal (name, out size, out module);
270                         if (data == (IntPtr) 0)
271                                 return null;
272                         else {
273                                 IntPtrStream stream = new IntPtrStream (data, size);
274                                 /* 
275                                  * The returned pointer points inside metadata, so
276                                  * we have to increase the refcount of the module, and decrease
277                                  * it when the stream is finalized.
278                                  */
279                                 stream.Closed += new EventHandler (new ResourceCloseHandler (module).OnClose);
280                                 return stream;
281                         }
282                 }
283
284                 public virtual Stream GetManifestResourceStream (Type type, String name)
285                 {
286                         string ns;
287                         if (type != null)
288                                 ns = type.Namespace;
289                         else 
290                                 ns = null;
291
292                         if ((ns == null) || (ns == ""))
293                                 return GetManifestResourceStream (name);
294                         else
295                                 return GetManifestResourceStream (ns + "." + name);
296                 }
297
298                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
299                 private extern Type[] GetTypes (bool exportedOnly);
300                 
301                 public virtual Type[] GetTypes ()
302                 {
303                         return GetTypes (false);
304                 }
305
306                 public virtual Type[] GetExportedTypes ()
307                 {
308                         return GetTypes (true);
309                 }
310
311                 public virtual Type GetType (String name, Boolean throwOnError)
312                 {
313                         return GetType (name, throwOnError, false);
314                 }
315
316                 public virtual Type GetType (String name) {
317                         return GetType (name, false, false);
318                 }
319
320                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
321                 internal extern Type InternalGetType (Module module, String name, Boolean throwOnError, Boolean ignoreCase);
322
323                 public Type GetType (string name, bool throwOnError, bool ignoreCase)
324                 {
325                         if (name == null)
326                                 throw new ArgumentNullException (name);
327
328                         return InternalGetType (null, name, throwOnError, ignoreCase);
329                 }
330
331                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
332                 internal extern static void InternalGetAssemblyName (string assemblyFile, AssemblyName aname);
333                 
334                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
335                 static extern void FillName (Assembly ass, AssemblyName aname);
336
337                 [MonoTODO ("true == not supported")]
338                 public virtual AssemblyName GetName (Boolean copiedName)
339                 {
340                         // CodeBase, which is restricted, will be copied into the AssemblyName object so...
341                         if (SecurityManager.SecurityEnabled) {
342                                 GetCodeBase (); // this will ensure the Demand is made
343                         }
344                         return UnprotectedGetName ();
345                 }
346
347                 public virtual AssemblyName GetName ()
348                 {
349                         return GetName (false);
350                 }
351
352                 // the security runtime requires access to the assemblyname (e.g. to get the strongname)
353                 internal AssemblyName UnprotectedGetName ()
354                 {
355                         AssemblyName aname = new AssemblyName ();
356                         FillName (this, aname);
357                         return aname;
358                 }
359
360                 public override string ToString ()
361                 {
362                         // note: ToString work without requiring CodeBase (so no checks are needed)
363                         AssemblyName aname = new AssemblyName ();
364                         FillName (this, aname);
365                         return aname.ToString ();
366                 }
367
368                 public static String CreateQualifiedName (String assemblyName, String typeName) 
369                 {
370                         return typeName + ", " + assemblyName;
371                 }
372
373                 public static Assembly GetAssembly (Type type)
374                 {
375                         if (type != null)
376                                 return type.Assembly;
377                         throw new ArgumentNullException ("type");
378                 }
379
380
381                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
382                 public static extern Assembly GetEntryAssembly();
383
384                 public Assembly GetSatelliteAssembly (CultureInfo culture)
385                 {
386                         return GetSatelliteAssembly (culture, null);
387                 }
388
389                 public Assembly GetSatelliteAssembly (CultureInfo culture, Version version)
390                 {
391                         if (culture == null)
392                                 throw new ArgumentException ("culture");
393
394                         AssemblyName aname = GetName (true);
395                         if (version != null)
396                                 aname.Version = version;
397
398                         aname.CultureInfo = culture;
399                         aname.Name = aname.Name + ".resources";
400                         return Load (aname);
401                 }
402                 
403                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
404                 private extern static Assembly LoadFrom (String assemblyFile, bool refonly);
405
406                 public static Assembly LoadFrom (String assemblyFile)
407                 {
408                         return LoadFrom (assemblyFile, false);
409                 }
410
411                 public static Assembly LoadFrom (String assemblyFile, Evidence securityEvidence)
412                 {
413                         Assembly a = LoadFrom (assemblyFile, false);
414                         if ((a != null) && (securityEvidence != null)) {
415                                 // merge evidence (i.e. replace defaults with provided evidences)
416                                 a.Evidence.Merge (securityEvidence);
417                         }
418                         return a;
419                 }
420
421 #if NET_1_1
422
423                 [MonoTODO]
424                 public static Assembly LoadFrom (String assemblyFile, Evidence securityEvidence, byte[] hashValue, AssemblyHashAlgorithm hashAlgorithm)
425                 {
426                         if (assemblyFile == null)
427                                 throw new ArgumentNullException ("assemblyFile");
428                         if (assemblyFile == String.Empty)
429                                 throw new ArgumentException ("Name can't be the empty string", "assemblyFile");
430                         throw new NotImplementedException ();
431                 }
432
433                 [MonoTODO]
434                 public static Assembly LoadFile (String path, Evidence securityEvidence) {
435                         if (path == null)
436                                 throw new ArgumentNullException ("path");
437                         if (path == String.Empty)
438                                 throw new ArgumentException ("Path can't be empty", "path");
439                         // FIXME: Make this do the right thing
440                         return LoadFrom (path, securityEvidence);
441                 }
442
443                 public static Assembly LoadFile (String path) {
444                         return LoadFile (path, null);
445                 }
446 #endif
447
448                 public static Assembly Load (String assemblyString)
449                 {
450                         return AppDomain.CurrentDomain.Load (assemblyString);
451                 }
452                 
453                 public static Assembly Load (String assemblyString, Evidence assemblySecurity)
454                 {
455                         return AppDomain.CurrentDomain.Load (assemblyString, assemblySecurity);
456                 }
457
458                 public static Assembly Load (AssemblyName assemblyRef)
459                 {
460                         return AppDomain.CurrentDomain.Load (assemblyRef);
461                 }
462
463                 public static Assembly Load (AssemblyName assemblyRef, Evidence assemblySecurity)
464                 {
465                         return AppDomain.CurrentDomain.Load (assemblyRef, assemblySecurity);
466                 }
467
468                 public static Assembly Load (Byte[] rawAssembly)
469                 {
470                         return AppDomain.CurrentDomain.Load (rawAssembly);
471                 }
472
473                 public static Assembly Load (Byte[] rawAssembly, Byte[] rawSymbolStore)
474                 {
475                         return AppDomain.CurrentDomain.Load (rawAssembly, rawSymbolStore);
476                 }
477
478                 public static Assembly Load (Byte[] rawAssembly, Byte[] rawSymbolStore,
479                                              Evidence securityEvidence)
480                 {
481                         return AppDomain.CurrentDomain.Load (rawAssembly, rawSymbolStore, securityEvidence);
482                 }
483
484 #if NET_2_0
485                 public static Assembly ReflectionOnlyLoad (byte[] rawAssembly)
486                 {
487                         return AppDomain.CurrentDomain.Load (rawAssembly, null, null, true);
488                 }
489
490                 public static Assembly ReflectionOnlyLoad (string assemblyName) 
491                 {
492                         return AppDomain.CurrentDomain.Load (assemblyName, null, true);
493                 }
494
495                 public static Assembly ReflectionOnlyLoadFrom (string assemblyFile) 
496                 {
497                         if (assemblyFile == null)
498                                 throw new ArgumentNullException ("assemblyFile");
499                         
500                         return LoadFrom (assemblyFile, true);
501                 }
502 #endif
503
504 #if NET_2_0
505                 [Obsolete ("")]
506 #endif
507                 public static Assembly LoadWithPartialName (string partialName)
508                 {
509                         return LoadWithPartialName (partialName, null);
510                 }
511
512                 [MonoTODO]
513                 public Module LoadModule (string moduleName, byte [] rawModule)
514                 {
515                         throw new NotImplementedException ();
516                 }
517
518                 [MonoTODO]
519                 public Module LoadModule (string moduleName, byte [] rawModule, byte [] rawSymbolStore)
520                 {
521                         throw new NotImplementedException ();
522                 }
523
524                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
525                 private static extern Assembly load_with_partial_name (string name, Evidence e);
526
527 #if NET_2_0
528                 [Obsolete ("")]
529 #endif
530                 public static Assembly LoadWithPartialName (string partialName, Evidence securityEvidence)
531                 {
532                         return LoadWithPartialName (partialName, securityEvidence, true);
533                 }
534
535                 /**
536                  * LAMESPEC: It is possible for this method to throw exceptions IF the name supplied
537                  * is a valid gac name and contains filesystem entry charachters at the end of the name
538                  * ie System/// will throw an exception. However ////System will not as that is canocolized
539                  * out of the name.
540                  */
541
542                 // FIXME: LoadWithPartialName must look cache (no CAS) or read from disk (CAS)
543 #if NET_2_0
544                 [Obsolete ("")]
545                 [ComVisible (false)]
546                 [MonoTODO]
547                 public
548 #else
549                 internal
550 #endif
551                 static Assembly LoadWithPartialName (string partialName, Evidence securityEvidence, bool oldBehavior)
552                 {
553                         if (!oldBehavior)
554                                 throw new NotImplementedException ();
555
556                         if (partialName == null)
557                                 throw new NullReferenceException ();
558
559                         return load_with_partial_name (partialName, securityEvidence);
560                 }
561
562                 public Object CreateInstance (String typeName) 
563                 {
564                         return CreateInstance (typeName, false);
565                 }
566
567                 public Object CreateInstance (String typeName, Boolean ignoreCase)
568                 {
569                         Type t = GetType (typeName, false, ignoreCase);
570                         if (t == null)
571                                 return null;
572
573                         try {
574                                 return Activator.CreateInstance (t);
575                         } catch (InvalidOperationException) {
576                                 throw new ArgumentException ("It is illegal to invoke a method on a Type loaded via ReflectionOnly methods.");
577                         }
578                 }
579
580                 public Object CreateInstance (String typeName, Boolean ignoreCase,
581                                               BindingFlags bindingAttr, Binder binder,
582                                               Object[] args, CultureInfo culture,
583                                               Object[] activationAttributes)
584                 {
585                         Type t = GetType (typeName, false, ignoreCase);
586                         if (t == null)
587                                 return null;
588
589                         try {
590                                 return Activator.CreateInstance (t, bindingAttr, binder, args, culture, activationAttributes);
591                         } catch (InvalidOperationException) {
592                                 throw new ArgumentException ("It is illegal to invoke a method on a Type loaded via ReflectionOnly methods.");
593                         }
594                 }
595
596                 public Module[] GetLoadedModules ()
597                 {
598                         return GetLoadedModules (false);
599                 }
600
601                 [MonoTODO]
602                 public Module[] GetLoadedModules (bool getResourceModules)
603                 {
604                         // Currently, the two sets of modules are equal
605                         return GetModules (getResourceModules);
606                 }
607
608                 public Module[] GetModules ()
609                 {
610                         return GetModules (false);
611                 }
612
613                 public Module GetModule (String name)
614                 {
615                         if (name == null)
616                                 throw new ArgumentNullException ("name");
617                         if (name == "")
618                                 throw new ArgumentException ("Name can't be empty");
619
620                         Module[] modules = GetModules (true);
621                         foreach (Module module in modules) {
622                                 if (module.ScopeName == name)
623                                         return module;
624                         }
625
626                         return null;
627                 }
628
629                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
630                 internal extern Module[] GetModulesInternal ();
631
632                 public Module[] GetModules (bool getResourceModules) {
633                         Module[] modules = GetModulesInternal ();
634
635                         if (!getResourceModules) {
636                                 ArrayList result = new ArrayList (modules.Length);
637                                 foreach (Module m in modules)
638                                         if (!m.IsResource ())
639                                                 result.Add (m);
640                                 return (Module[])result.ToArray (typeof (Module));
641                         }
642                         else
643                                 return modules;
644                 }
645
646                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
647                 internal extern string[] GetNamespaces ();
648                 
649                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
650                 public extern virtual String[] GetManifestResourceNames ();
651
652                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
653                 public extern static Assembly GetExecutingAssembly ();
654
655                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
656                 public extern static Assembly GetCallingAssembly ();
657
658                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
659                 public extern AssemblyName[] GetReferencedAssemblies ();
660
661                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
662                 private extern bool GetManifestResourceInfoInternal (String name, ManifestResourceInfo info);
663
664                 public virtual ManifestResourceInfo GetManifestResourceInfo (String resourceName)
665                 {
666                         if (resourceName == null)
667                                 throw new ArgumentNullException ("resourceName");
668                         if (resourceName == "")
669                                 throw new ArgumentException ("String cannot have zero length.");
670                         ManifestResourceInfo result = new ManifestResourceInfo ();
671                         bool found = GetManifestResourceInfoInternal (resourceName, result);
672                         if (found)
673                                 return result;
674                         else
675                                 return null;
676                 }
677
678                 private class ResourceCloseHandler {
679
680                         Module module;
681
682                         public ResourceCloseHandler (Module module) {
683                                 this.module = module;
684                         }
685
686                         public void OnClose (object sender, EventArgs e) {
687                                 // The module dtor will take care of things
688                                 module = null;
689                         }
690                 }
691
692                 //
693                 // The following functions are only for the Mono Debugger.
694                 //
695
696                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
697                 internal static extern MethodBase MonoDebugger_GetMethod (Assembly assembly, int token);
698
699                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
700                 internal static extern int MonoDebugger_GetMethodToken (Assembly assembly, MethodBase method);
701
702                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
703                 internal static extern Type MonoDebugger_GetLocalTypeFromSignature (Assembly assembly, byte[] signature);
704
705                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
706                 internal static extern Type MonoDebugger_GetType (Assembly assembly, int token);
707
708                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
709                 internal static extern string MonoDebugger_CheckRuntimeVersion (string filename);
710
711                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
712                 internal static extern string MonoDebugger_GetMethodIndex (MethodBase method);
713
714                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
715                 internal static extern Type MonoDebugger_MakeArrayType (Type type, int rank);
716
717                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
718                 internal static extern int MonoDebugger_GetTypeToken (Type type);
719
720 #if NET_2_0
721                 [MonoTODO]
722                 [ComVisible (false)]
723                 public long HostContext {
724                         get { return 0; }
725                 }
726
727                 [ComVisible (false)]
728                 public ImageFileMachine ImageFileMachine {
729                         get {
730                                 ImageFileMachine machine;
731                                 PortableExecutableKind kind;
732                                 ModuleHandle handle = ManifestModule.ModuleHandle;
733                                 handle.GetPEKind (out kind, out machine);
734                                 return machine;
735                         }
736                 }
737
738                 [ComVisible (false)]
739                 public extern Module ManifestModule {
740                         [MethodImplAttribute (MethodImplOptions.InternalCall)]
741                         get;
742                 }
743
744                 [ComVisible (false)]
745                 public extern int MetadataToken {
746                         [MethodImplAttribute (MethodImplOptions.InternalCall)]
747                         get;
748                 }
749
750                 [ComVisible (false)]
751                 public PortableExecutableKind PortableExecutableKind {
752                         get {
753                                 ImageFileMachine machine;
754                                 PortableExecutableKind kind;
755                                 ModuleHandle handle = ManifestModule.ModuleHandle;
756                                 handle.GetPEKind (out kind, out machine);
757                                 return kind;
758                         }
759                 }
760
761                 [ComVisible (false)]
762                 public virtual extern bool ReflectionOnly {
763                         [MethodImplAttribute (MethodImplOptions.InternalCall)]
764                         get;
765                 }
766 #endif
767
768                 // Code Access Security
769
770                 internal void Resolve () 
771                 {
772                         lock (this) {
773                                 // FIXME: As we (currently) delay the resolution until the first CAS
774                                 // Demand it's too late to evaluate the Minimum permission set as a 
775                                 // condition to load the assembly into the AppDomain
776                                 LoadAssemblyPermissions ();
777                                 _granted = SecurityManager.ResolvePolicy (UnprotectedGetEvidence (),
778                                         _minimum, _optional, _refuse, out _denied);
779                         }
780 #if false
781                         Console.WriteLine ("*** ASSEMBLY RESOLVE INPUT ***");
782                         if (_minimum != null)
783                                 Console.WriteLine ("Minimum: {0}", _minimum);
784                         if (_optional != null)
785                                 Console.WriteLine ("Optional: {0}", _optional);
786                         if (_refuse != null)
787                                 Console.WriteLine ("Refuse: {0}", _refuse);
788                         Console.WriteLine ("*** ASSEMBLY RESOLVE RESULTS ***");
789                         Console.WriteLine ("Granted: {0}", _granted);
790                         if (_denied != null)
791                                 Console.WriteLine ("Denied: {0}", _denied);
792                         Console.WriteLine ("*** ASSEMBLY RESOLVE END ***");
793 #endif
794                 }
795
796                 internal PermissionSet GrantedPermissionSet {
797                         get {
798                                 if (_granted == null) {
799                                         Resolve ();
800                                 }
801                                 return _granted;
802                         }
803                 }
804
805                 internal PermissionSet DeniedPermissionSet {
806                         get {
807                                 // yes we look for granted, as denied may be null
808                                 if (_granted == null) {
809                                         Resolve ();
810                                 }
811                                 return _denied;
812                         }
813                 }
814
815                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
816                 extern internal static bool LoadPermissions (Assembly a, 
817                         ref IntPtr minimum, ref int minLength,
818                         ref IntPtr optional, ref int optLength,
819                         ref IntPtr refused, ref int refLength);
820
821                 // Support for SecurityAction.RequestMinimum, RequestOptional and RequestRefuse
822                 private void LoadAssemblyPermissions ()
823                 {
824                         IntPtr minimum = IntPtr.Zero, optional = IntPtr.Zero, refused = IntPtr.Zero;
825                         int minLength = 0, optLength = 0, refLength = 0;
826                         if (LoadPermissions (this, ref minimum, ref minLength, ref optional,
827                                 ref optLength, ref refused, ref refLength)) {
828
829                                 // Note: no need to cache these permission sets as they will only be created once
830                                 // at assembly resolution time.
831                                 if (minLength > 0) {
832                                         byte[] data = new byte [minLength];
833                                         Marshal.Copy (minimum, data, 0, minLength);
834                                         _minimum = SecurityManager.Decode (data);
835                                 }
836                                 if (optLength > 0) {
837                                         byte[] data = new byte [optLength];
838                                         Marshal.Copy (optional, data, 0, optLength);
839                                         _optional = SecurityManager.Decode (data);
840                                 }
841                                 if (refLength > 0) {
842                                         byte[] data = new byte [refLength];
843                                         Marshal.Copy (refused, data, 0, refLength);
844                                         _refuse = SecurityManager.Decode (data);
845                                 }
846                         }
847                 }
848         }
849 }