Halve the stack depth for both the new single step tests
[mono.git] / mcs / class / referencesource / mscorlib / system / runtime / interopservices / typelibconverter.cs
1 // ==++==
2 // 
3 //   Copyright (c) Microsoft Corporation.  All rights reserved.
4 // 
5 // ==--==
6 /*=============================================================================
7 **
8 ** Class: TypeLibConverter
9 **
10 **
11 ** Purpose: Component that implements the ITypeLibConverter interface and
12 **          does the actual work of converting a typelib to metadata and
13 **          vice versa.
14 **
15 **
16 =============================================================================*/
17 #if !FEATURE_CORECLR // current implementation requires reflection only load 
18 namespace System.Runtime.InteropServices {
19    
20     using System;
21     using System.Diagnostics.Contracts;
22     using System.Collections;
23     using System.Collections.Generic;
24     using System.Threading;
25     using System.Runtime.InteropServices.TCEAdapterGen;
26     using System.IO;
27     using System.Reflection;
28     using System.Reflection.Emit;
29     using System.Configuration.Assemblies;
30     using Microsoft.Win32;
31     using System.Runtime.CompilerServices;
32     using System.Globalization;
33     using System.Security;
34     using System.Security.Permissions;
35     using System.Runtime.InteropServices.ComTypes;
36     using System.Runtime.Versioning;
37     using WORD = System.UInt16;
38     using DWORD = System.UInt32;
39     using _TYPELIBATTR = System.Runtime.InteropServices.ComTypes.TYPELIBATTR;
40
41     [Guid("F1C3BF79-C3E4-11d3-88E7-00902754C43A")]
42     [ClassInterface(ClassInterfaceType.None)]
43 [System.Runtime.InteropServices.ComVisible(true)]
44     public sealed class TypeLibConverter : ITypeLibConverter
45     {
46         private const String s_strTypeLibAssemblyTitlePrefix = "TypeLib ";
47         private const String s_strTypeLibAssemblyDescPrefix = "Assembly generated from typelib ";
48         private const int MAX_NAMESPACE_LENGTH = 1024;
49
50
51         //
52         // ITypeLibConverter interface.
53         //
54
55         [System.Security.SecuritySafeCritical]  // auto-generated
56         [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.UnmanagedCode)]
57         [ResourceExposure(ResourceScope.Machine)]
58         [ResourceConsumption(ResourceScope.Machine)]
59         public AssemblyBuilder ConvertTypeLibToAssembly([MarshalAs(UnmanagedType.Interface)] Object typeLib, 
60                                                         String asmFileName,
61                                                         int flags,
62                                                         ITypeLibImporterNotifySink notifySink,
63                                                         byte[] publicKey,
64                                                         StrongNameKeyPair keyPair,
65                                                         bool unsafeInterfaces)
66         {
67             return ConvertTypeLibToAssembly(typeLib,
68                                             asmFileName,
69                                             (unsafeInterfaces
70                                                 ? TypeLibImporterFlags.UnsafeInterfaces
71                                                 : 0),
72                                             notifySink,
73                                             publicKey,
74                                             keyPair,
75                                             null,
76                                             null);
77         }
78
79
80
81
82         [System.Security.SecuritySafeCritical]  // auto-generated
83         [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.UnmanagedCode)]
84         [ResourceExposure(ResourceScope.Machine)]
85         [ResourceConsumption(ResourceScope.Machine)]
86         public AssemblyBuilder ConvertTypeLibToAssembly([MarshalAs(UnmanagedType.Interface)] Object typeLib, 
87                                                         String asmFileName,
88                                                         TypeLibImporterFlags flags, 
89                                                         ITypeLibImporterNotifySink notifySink,
90                                                         byte[] publicKey,
91                                                         StrongNameKeyPair keyPair,
92                                                         String asmNamespace,
93                                                         Version asmVersion)
94         {
95             // Validate the arguments.
96             if (typeLib == null)
97                 throw new ArgumentNullException("typeLib");
98             if (asmFileName == null)
99                 throw new ArgumentNullException("asmFileName");         
100             if (notifySink == null)
101                 throw new ArgumentNullException("notifySink");
102             if (String.Empty.Equals(asmFileName))
103                 throw new ArgumentException(Environment.GetResourceString("Arg_InvalidFileName"), "asmFileName");
104             if (asmFileName.Length > Path.MAX_PATH)
105                 throw new ArgumentException(Environment.GetResourceString("IO.PathTooLong"), asmFileName);
106             if ((flags & TypeLibImporterFlags.PrimaryInteropAssembly) != 0 && publicKey == null && keyPair == null)
107                 throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_PIAMustBeStrongNamed"));
108             Contract.EndContractBlock();
109
110             ArrayList eventItfInfoList = null;
111
112             // Determine the AssemblyNameFlags
113             AssemblyNameFlags asmNameFlags = AssemblyNameFlags.None;
114             
115             // Retrieve the assembly name from the typelib.
116             AssemblyName asmName = GetAssemblyNameFromTypelib(typeLib, asmFileName, publicKey, keyPair, asmVersion, asmNameFlags);
117
118             // Create the dynamic assembly that will contain the converted typelib types.
119             AssemblyBuilder asmBldr = CreateAssemblyForTypeLib(typeLib, asmFileName, asmName, 
120                                         (flags & TypeLibImporterFlags.PrimaryInteropAssembly) != 0,
121                                         (flags & TypeLibImporterFlags.ReflectionOnlyLoading) != 0,
122                                         (flags & TypeLibImporterFlags.NoDefineVersionResource) != 0);
123
124             // Define a dynamic module that will contain the contain the imported types.
125             String strNonQualifiedAsmFileName = Path.GetFileName(asmFileName);
126             ModuleBuilder modBldr = asmBldr.DefineDynamicModule(strNonQualifiedAsmFileName, strNonQualifiedAsmFileName);
127
128             // If the namespace hasn't been specified, then use the assembly name.
129             if (asmNamespace == null)
130                 asmNamespace = asmName.Name;
131
132             // Create a type resolve handler that will also intercept resolve ref messages
133             // on the sink interface to build up a list of referenced assemblies.
134             TypeResolveHandler typeResolveHandler = new TypeResolveHandler(modBldr, notifySink);
135
136             // Add a listener for the type resolve events.
137             AppDomain currentDomain = Thread.GetDomain();
138             ResolveEventHandler resolveHandler = new ResolveEventHandler(typeResolveHandler.ResolveEvent);
139             ResolveEventHandler asmResolveHandler = new ResolveEventHandler(typeResolveHandler.ResolveAsmEvent);
140             ResolveEventHandler ROAsmResolveHandler = new ResolveEventHandler(typeResolveHandler.ResolveROAsmEvent);
141             currentDomain.TypeResolve += resolveHandler;
142             currentDomain.AssemblyResolve += asmResolveHandler;
143             currentDomain.ReflectionOnlyAssemblyResolve += ROAsmResolveHandler;
144
145             // Convert the types contained in the typelib into metadata and add them to the assembly.
146             nConvertTypeLibToMetadata(typeLib, asmBldr.InternalAssembly, modBldr.InternalModule, asmNamespace, flags, typeResolveHandler, out eventItfInfoList);
147
148             // Update the COM types in the assembly.
149             UpdateComTypesInAssembly(asmBldr, modBldr);
150
151             // If there are any event sources then generate the TCE adapters.
152             if (eventItfInfoList.Count > 0)
153                 new TCEAdapterGenerator().Process(modBldr, eventItfInfoList);
154
155             // Remove the listener for the type resolve events.
156             currentDomain.TypeResolve -= resolveHandler;
157             currentDomain.AssemblyResolve -= asmResolveHandler;
158             currentDomain.ReflectionOnlyAssemblyResolve -= ROAsmResolveHandler;
159
160             // We have finished converting the typelib and now have a fully formed assembly.
161             return asmBldr;
162         }
163
164         [System.Security.SecuritySafeCritical]  // auto-generated
165         [ResourceExposure(ResourceScope.Machine)]
166         [ResourceConsumption(ResourceScope.Machine)]
167         [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.UnmanagedCode)]
168         [return : MarshalAs(UnmanagedType.Interface)]
169         public Object ConvertAssemblyToTypeLib(Assembly assembly, String strTypeLibName, TypeLibExporterFlags flags, ITypeLibExporterNotifySink notifySink)
170         {
171             RuntimeAssembly rtAssembly;
172             AssemblyBuilder ab = assembly as AssemblyBuilder;
173             if (ab != null)
174                 rtAssembly = ab.InternalAssembly;
175             else
176                 rtAssembly = assembly as RuntimeAssembly;
177
178             return nConvertAssemblyToTypeLib(rtAssembly, strTypeLibName, flags, notifySink);
179         }
180
181         [ResourceExposure(ResourceScope.Machine)]
182         [ResourceConsumption(ResourceScope.Machine)]
183         public bool GetPrimaryInteropAssembly(Guid g, Int32 major, Int32 minor, Int32 lcid, out String asmName, out String asmCodeBase)
184         {
185             String strTlbId = "{" + g.ToString().ToUpper(CultureInfo.InvariantCulture) + "}";
186             String strVersion = major.ToString("x", CultureInfo.InvariantCulture) + "." + minor.ToString("x", CultureInfo.InvariantCulture);
187
188             // Set the two out values to null before we start.
189             asmName = null;
190             asmCodeBase = null;
191
192             // Try to open the HKEY_CLASS_ROOT\TypeLib key.
193             using (RegistryKey TypeLibKey = Registry.ClassesRoot.OpenSubKey("TypeLib", false))
194             {
195                 if (TypeLibKey != null)
196                 {
197                     // Try to open the HKEY_CLASS_ROOT\TypeLib\<TLBID> key.            
198                     using (RegistryKey TypeLibSubKey = TypeLibKey.OpenSubKey(strTlbId))
199                     {
200                         if (TypeLibSubKey != null)
201                         {
202                             // Try to open the HKEY_CLASS_ROOT\TypeLib\<TLBID>\<Major.Minor> key.
203                             using (RegistryKey VersionKey = TypeLibSubKey.OpenSubKey(strVersion, false))
204                             {
205                                 if (VersionKey != null)
206                                 {
207                                     // Attempt to retrieve the assembly name and codebase under the version key.
208                                     asmName = (String)VersionKey.GetValue("PrimaryInteropAssemblyName");
209                                     asmCodeBase = (String)VersionKey.GetValue("PrimaryInteropAssemblyCodeBase");
210                                 }
211                             }
212                         }
213                     }
214                 }
215             }
216             
217             // If the assembly name isn't null, then we found an PIA.
218             return asmName != null;
219         }
220
221
222         //
223         // Non native helper methods.
224         //
225
226         [System.Security.SecurityCritical]  // auto-generated
227         [ResourceExposure(ResourceScope.Machine)]
228         [ResourceConsumption(ResourceScope.Machine)]
229         [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
230         private static AssemblyBuilder CreateAssemblyForTypeLib(Object typeLib, String asmFileName, AssemblyName asmName, bool bPrimaryInteropAssembly, bool bReflectionOnly, bool bNoDefineVersionResource)
231         {
232             // Retrieve the current app domain.
233             AppDomain currentDomain = Thread.GetDomain();
234
235             // Retrieve the directory from the assembly file name.
236             String dir = null;
237             if (asmFileName != null)
238             {
239                 dir = Path.GetDirectoryName(asmFileName);
240                 if (String.IsNullOrEmpty(dir))
241                     dir = null;
242             }
243
244             AssemblyBuilderAccess aba;
245             if (bReflectionOnly)
246             {
247                 aba = AssemblyBuilderAccess.ReflectionOnly;
248             }
249             else
250             {
251                 aba = AssemblyBuilderAccess.RunAndSave;
252             }
253
254             // Create the dynamic assembly itself.
255             AssemblyBuilder asmBldr;
256
257             List<CustomAttributeBuilder> assemblyAttributes = new List<CustomAttributeBuilder>();
258 #if !FEATURE_CORECLR
259             // mscorlib.dll must specify the security rules that assemblies it emits are to use, since by
260             // default all assemblies will follow security rule set level 2, and we want to make that an
261             // explicit decision.
262             ConstructorInfo securityRulesCtor = typeof(SecurityRulesAttribute).GetConstructor(new Type[] { typeof(SecurityRuleSet) });
263             CustomAttributeBuilder securityRulesAttribute =
264                 new CustomAttributeBuilder(securityRulesCtor, new object[] { SecurityRuleSet.Level2 });
265             assemblyAttributes.Add(securityRulesAttribute);
266 #endif // !FEATURE_CORECLR
267
268             asmBldr = currentDomain.DefineDynamicAssembly(asmName, aba, dir, false, assemblyAttributes);
269
270             // Set the Guid custom attribute on the assembly.
271             SetGuidAttributeOnAssembly(asmBldr, typeLib);
272
273             // Set the imported from COM attribute on the assembly and return it.
274             SetImportedFromTypeLibAttrOnAssembly(asmBldr, typeLib);
275
276             // Set the version information on the typelib.
277             if (bNoDefineVersionResource)
278             {
279                 SetTypeLibVersionAttribute(asmBldr, typeLib);
280             }
281             else
282             {
283             SetVersionInformation(asmBldr, typeLib, asmName);
284             }
285
286             // If we are generating a PIA, then set the PIA custom attribute.
287             if (bPrimaryInteropAssembly)
288                 SetPIAAttributeOnAssembly(asmBldr, typeLib);
289
290             return asmBldr;
291         }
292
293         [System.Security.SecurityCritical]  // auto-generated
294         internal static AssemblyName GetAssemblyNameFromTypelib(Object typeLib, String asmFileName, byte[] publicKey, StrongNameKeyPair keyPair, Version asmVersion, AssemblyNameFlags asmNameFlags)
295         {
296             // Extract the name of the typelib.
297             String strTypeLibName = null;
298             String strDocString = null;
299             int dwHelpContext = 0;
300             String strHelpFile = null;
301             ITypeLib pTLB = (ITypeLib)typeLib;
302             pTLB.GetDocumentation(-1, out strTypeLibName, out strDocString, out dwHelpContext, out strHelpFile);
303
304             // Retrieve the name to use for the assembly.
305             if (asmFileName == null)
306             {
307                 asmFileName = strTypeLibName;
308             }
309             else
310             {
311                 Contract.Assert((asmFileName != null) && (asmFileName.Length > 0), "The assembly file name cannot be an empty string!");
312
313                 String strFileNameNoPath = Path.GetFileName(asmFileName);
314                 String strExtension = Path.GetExtension(asmFileName);
315
316                 // Validate that the extension is valid.
317                 bool bExtensionValid = ".dll".Equals(strExtension, StringComparison.OrdinalIgnoreCase);
318
319                 // If the extension is not valid then tell the user and quit.
320                 if (!bExtensionValid)
321                     throw new ArgumentException(Environment.GetResourceString("Arg_InvalidFileExtension"));
322
323                 // The assembly cannot contain the path nor the extension.
324                 asmFileName = strFileNameNoPath.Substring(0, strFileNameNoPath.Length - ".dll".Length);
325             }
326
327             // If the version information was not specified, then retrieve it from the typelib.
328             if (asmVersion == null)
329             {
330                 int major;
331                 int minor;
332                 Marshal.GetTypeLibVersion(pTLB, out major, out minor);
333                 asmVersion = new Version(major, minor, 0, 0);
334             }
335             
336             // Create the assembly name for the imported typelib's assembly.
337             AssemblyName AsmName = new AssemblyName();
338             AsmName.Init(
339                 asmFileName,
340                 publicKey,
341                 null,
342                 asmVersion,
343                 null,
344                 AssemblyHashAlgorithm.None,
345                 AssemblyVersionCompatibility.SameMachine,
346                 null,
347                 asmNameFlags,
348                 keyPair);
349
350             return AsmName;
351         }
352
353         private static void UpdateComTypesInAssembly(AssemblyBuilder asmBldr, ModuleBuilder modBldr)
354         {
355             // Retrieve the AssemblyBuilderData associated with the assembly builder.
356             AssemblyBuilderData AsmBldrData = asmBldr.m_assemblyData;
357
358             // Go through the types in the module and add them as public COM types.
359             Type[] aTypes = modBldr.GetTypes();
360             int NumTypes = aTypes.Length;
361             for (int cTypes = 0; cTypes < NumTypes; cTypes++)
362                 AsmBldrData.AddPublicComType(aTypes[cTypes]);
363         }
364
365
366         [System.Security.SecurityCritical]  // auto-generated
367         private static void SetGuidAttributeOnAssembly(AssemblyBuilder asmBldr, Object typeLib)
368         {
369             // Retrieve the GuidAttribute constructor.
370             Type []aConsParams = new Type[1] {typeof(String)};
371             ConstructorInfo GuidAttrCons = typeof(GuidAttribute).GetConstructor(aConsParams);
372
373             // Create an instance of the custom attribute builder.
374             Object[] aArgs = new Object[1] {Marshal.GetTypeLibGuid((ITypeLib)typeLib).ToString()};
375             CustomAttributeBuilder GuidCABuilder = new CustomAttributeBuilder(GuidAttrCons, aArgs);
376
377             // Set the GuidAttribute on the assembly builder.
378             asmBldr.SetCustomAttribute(GuidCABuilder);
379         }
380
381         [System.Security.SecurityCritical]  // auto-generated
382         private static void SetImportedFromTypeLibAttrOnAssembly(AssemblyBuilder asmBldr, Object typeLib)
383         {
384             // Retrieve the ImportedFromTypeLibAttribute constructor.
385             Type []aConsParams = new Type[1] {typeof(String)};
386             ConstructorInfo ImpFromComAttrCons = typeof(ImportedFromTypeLibAttribute).GetConstructor(aConsParams);
387
388             // Retrieve the name of the typelib.
389             String strTypeLibName = Marshal.GetTypeLibName((ITypeLib)typeLib);
390
391             // Create an instance of the custom attribute builder.
392             Object[] aArgs = new Object[1] {strTypeLibName};
393             CustomAttributeBuilder ImpFromComCABuilder = new CustomAttributeBuilder(ImpFromComAttrCons, aArgs);
394
395             // Set the ImportedFromTypeLibAttribute on the assembly builder.
396             asmBldr.SetCustomAttribute(ImpFromComCABuilder);
397         }
398
399         [System.Security.SecurityCritical]  // auto-generated
400         private static void SetTypeLibVersionAttribute(AssemblyBuilder asmBldr, Object typeLib)
401         {
402             Type []aConsParams = new Type[2] {typeof(int), typeof(int)};
403             ConstructorInfo TypeLibVerCons = typeof(TypeLibVersionAttribute).GetConstructor(aConsParams);
404
405             // Get the typelib version
406             int major;
407             int minor;
408             Marshal.GetTypeLibVersion((ITypeLib)typeLib, out major, out minor);
409             
410             // Create an instance of the custom attribute builder.
411             Object[] aArgs = new Object[2] {major, minor};
412             CustomAttributeBuilder TypeLibVerBuilder = new CustomAttributeBuilder(TypeLibVerCons, aArgs);
413
414             // Set the attribute on the assembly builder.
415             asmBldr.SetCustomAttribute(TypeLibVerBuilder);
416         }
417
418         [System.Security.SecurityCritical]  // auto-generated
419         private static void SetVersionInformation(AssemblyBuilder asmBldr, Object typeLib, AssemblyName asmName)
420         {
421             // Extract the name of the typelib.
422             String strTypeLibName = null;
423             String strDocString = null;
424             int dwHelpContext = 0;
425             String strHelpFile = null;
426             ITypeLib pTLB = (ITypeLib)typeLib;
427             pTLB.GetDocumentation(-1, out strTypeLibName, out strDocString, out dwHelpContext, out strHelpFile);
428
429             // Generate the product name string from the named of the typelib.
430             String strProductName = String.Format(CultureInfo.InvariantCulture, Environment.GetResourceString("TypeLibConverter_ImportedTypeLibProductName"), strTypeLibName);
431
432             // Set the OS version information.
433             asmBldr.DefineVersionInfoResource(strProductName, asmName.Version.ToString(), null, null, null);
434
435             // Set the TypeLibVersion attribute
436             SetTypeLibVersionAttribute(asmBldr, typeLib);
437         }
438
439         [System.Security.SecurityCritical]  // auto-generated
440         private static void SetPIAAttributeOnAssembly(AssemblyBuilder asmBldr, Object typeLib)
441         {
442             IntPtr pAttr = IntPtr.Zero;
443             _TYPELIBATTR Attr;
444             ITypeLib pTLB = (ITypeLib)typeLib;
445             int Major = 0;
446             int Minor = 0;
447
448             // Retrieve the PrimaryInteropAssemblyAttribute constructor.
449             Type []aConsParams = new Type[2] {typeof(int), typeof(int)};
450             ConstructorInfo PIAAttrCons = typeof(PrimaryInteropAssemblyAttribute).GetConstructor(aConsParams);
451
452             // Retrieve the major and minor version from the typelib.
453             try
454             {
455                 pTLB.GetLibAttr(out pAttr);
456                 Attr = (_TYPELIBATTR)Marshal.PtrToStructure(pAttr, typeof(_TYPELIBATTR));
457                 Major = Attr.wMajorVerNum;
458                 Minor = Attr.wMinorVerNum;
459             }
460             finally
461             {
462                 // Release the typelib attributes.
463                 if (pAttr != IntPtr.Zero)
464                     pTLB.ReleaseTLibAttr(pAttr);
465             }
466
467             // Create an instance of the custom attribute builder.
468             Object[] aArgs = new Object[2] {Major, Minor};
469             CustomAttributeBuilder PIACABuilder = new CustomAttributeBuilder(PIAAttrCons, aArgs);
470
471             // Set the PrimaryInteropAssemblyAttribute on the assembly builder.
472             asmBldr.SetCustomAttribute(PIACABuilder);
473         }
474
475
476         //
477         // Native helper methods.
478         //
479
480         [System.Security.SecurityCritical]  // auto-generated
481         [ResourceExposure(ResourceScope.None)]
482         [MethodImplAttribute(MethodImplOptions.InternalCall)] 
483         private static extern void nConvertTypeLibToMetadata(Object typeLib, RuntimeAssembly asmBldr, RuntimeModule modBldr, String nameSpace, TypeLibImporterFlags flags, ITypeLibImporterNotifySink notifySink, out ArrayList eventItfInfoList);
484
485         // Must use assembly versioning or GuidAttribute to avoid collisions in typelib export or registration.
486         [System.Security.SecurityCritical]  // auto-generated
487         [ResourceExposure(ResourceScope.Machine)]
488         [MethodImplAttribute(MethodImplOptions.InternalCall)] 
489         private static extern Object nConvertAssemblyToTypeLib(RuntimeAssembly assembly, String strTypeLibName, TypeLibExporterFlags flags, ITypeLibExporterNotifySink notifySink);
490
491         [System.Security.SecurityCritical]  // auto-generated
492         [ResourceExposure(ResourceScope.None)]
493         [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity]
494         internal extern static void LoadInMemoryTypeByName(RuntimeModule module, String className);
495
496         //
497         // Helper class called when a resolve type event is fired.
498         //
499
500         private class TypeResolveHandler : ITypeLibImporterNotifySink
501         {
502             public TypeResolveHandler(ModuleBuilder mod, ITypeLibImporterNotifySink userSink)
503             {
504                 m_Module = mod;
505                 m_UserSink = userSink;
506             }
507
508             public void ReportEvent(ImporterEventKind eventKind, int eventCode, String eventMsg)
509             {
510                 m_UserSink.ReportEvent(eventKind, eventCode, eventMsg);
511             }
512
513             public Assembly ResolveRef(Object typeLib)
514             {
515                 Contract.Ensures(Contract.Result<Assembly>() != null && Contract.Result<Assembly>() is RuntimeAssembly);
516                 Contract.EndContractBlock();
517
518                 // Call the user sink to resolve the reference.
519                 Assembly asm = m_UserSink.ResolveRef(typeLib);
520
521                 if (asm == null)
522                     throw new ArgumentNullException();
523
524                 // Return the resolved assembly. We extract the internal assembly because we are called
525                 // by the VM which accesses fields of the object directly and does not go via those
526                 // delegating properties (the fields are empty if asm is an (external) AssemblyBuilder).
527
528                 RuntimeAssembly rtAssembly = asm as RuntimeAssembly;
529                 if (rtAssembly == null)
530                 {
531                     AssemblyBuilder ab = asm as AssemblyBuilder;
532                     if (ab != null)
533                         rtAssembly = ab.InternalAssembly;
534                 }
535
536                 if (rtAssembly == null)
537                     throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeAssembly"));
538
539                 // Add the assembly to the list of assemblies.
540                 m_AsmList.Add(rtAssembly);
541
542                 return rtAssembly;
543             }
544
545             [System.Security.SecurityCritical]  // auto-generated
546             public Assembly ResolveEvent(Object sender, ResolveEventArgs args)
547             {
548                 // We need to load the type in the resolve event so that we will deal with
549                 // cases where we are trying to load the CoClass before the interface has 
550                 // been loaded.               
551                 try
552                 {
553                     LoadInMemoryTypeByName(m_Module.GetNativeHandle(), args.Name); 
554                     return m_Module.Assembly;
555                 }
556                 catch (TypeLoadException e)
557                 {
558                     if (e.ResourceId != System.__HResults.COR_E_TYPELOAD)  // type not found
559                         throw;
560                 }
561
562                 foreach (RuntimeAssembly asm in m_AsmList)
563                 {
564                     try
565                     {
566                         asm.GetType(args.Name, true, false);
567                         return asm;
568                     }
569                     catch (TypeLoadException e)
570                     {
571                         if (e._HResult != System.__HResults.COR_E_TYPELOAD)  // type not found
572                             throw;
573                     }
574                 }
575                 
576                 return null;
577             }
578
579             public Assembly ResolveAsmEvent(Object sender, ResolveEventArgs args)
580             {
581                 foreach (RuntimeAssembly asm in m_AsmList)
582                 {
583                     if (String.Compare(asm.FullName, args.Name, StringComparison.OrdinalIgnoreCase) == 0)
584                         return asm;
585                 }
586
587                 return null;
588             }
589
590             public Assembly ResolveROAsmEvent(Object sender, ResolveEventArgs args)
591             {
592                 foreach (RuntimeAssembly asm in m_AsmList)
593                 {
594                     if (String.Compare(asm.FullName, args.Name, StringComparison.OrdinalIgnoreCase) == 0)
595                         return asm;
596                 }
597
598                 // We failed to find the referenced assembly in our pre-loaded assemblies, so try to load it based on policy.
599                 string asmName = AppDomain.CurrentDomain.ApplyPolicy(args.Name);
600                 return Assembly.ReflectionOnlyLoad(asmName);
601             }
602
603             private ModuleBuilder m_Module;
604             private ITypeLibImporterNotifySink m_UserSink;
605             private List<RuntimeAssembly> m_AsmList = new List<RuntimeAssembly>();
606         }
607     }
608 }
609 #endif // !FEATURE_CORECLR // current implementation requires reflection only load
610