summaryrefslogtreecommitdiff
path: root/src/mscorlib/src/System/Reflection/Emit/AssemblyBuilder.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/mscorlib/src/System/Reflection/Emit/AssemblyBuilder.cs')
-rw-r--r--src/mscorlib/src/System/Reflection/Emit/AssemblyBuilder.cs2245
1 files changed, 2245 insertions, 0 deletions
diff --git a/src/mscorlib/src/System/Reflection/Emit/AssemblyBuilder.cs b/src/mscorlib/src/System/Reflection/Emit/AssemblyBuilder.cs
new file mode 100644
index 0000000000..5e7f83f2df
--- /dev/null
+++ b/src/mscorlib/src/System/Reflection/Emit/AssemblyBuilder.cs
@@ -0,0 +1,2245 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+
+//*************************************************************************************************************
+// For each dynamic assembly there will be two AssemblyBuilder objects: the "internal"
+// AssemblyBuilder object and the "external" AssemblyBuilder object.
+// 1. The "internal" object is the real assembly object that the VM creates and knows about. However,
+// you can perform RefEmit operations on it only if you have its granted permission. From the AppDomain
+// and other "internal" objects like the "internal" ModuleBuilders and runtime types, you can only
+// get the "internal" objects. This is to prevent low-trust code from getting a hold of the dynamic
+// AssemblyBuilder/ModuleBuilder/TypeBuilder/MethodBuilder/etc other people have created by simply
+// enumerating the AppDomain and inject code in it.
+// 2. The "external" object is merely an wrapper of the "internal" object and all operations on it
+// are directed to the internal object. This is the one you get by calling DefineDynamicAssembly
+// on AppDomain and the one you can always perform RefEmit operations on. You can get other "external"
+// objects from the "external" AssemblyBuilder, ModuleBuilder, TypeBuilder, MethodBuilder, etc. Note
+// that VM doesn't know about this object. So every time we call into the VM we need to pass in the
+// "internal" object.
+//
+// "internal" and "external" ModuleBuilders are similar
+//*************************************************************************************************************
+
+namespace System.Reflection.Emit
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Diagnostics;
+ using System.Diagnostics.Contracts;
+ using System.Diagnostics.SymbolStore;
+ using CultureInfo = System.Globalization.CultureInfo;
+ using System.IO;
+ using System.Reflection;
+ using System.Resources;
+ using System.Runtime.CompilerServices;
+ using System.Runtime.InteropServices;
+ using System.Runtime.Serialization;
+ using System.Runtime.Versioning;
+ using System.Security;
+ using System.Security.Permissions;
+ using System.Security.Policy;
+ using System.Threading;
+
+ // These must match the definitions in Assembly.hpp
+ [Flags]
+ internal enum DynamicAssemblyFlags
+ {
+ None = 0x00000000,
+
+ // Security attributes which affect the module security descriptor
+ AllCritical = 0x00000001,
+ Aptca = 0x00000002,
+ Critical = 0x00000004,
+ Transparent = 0x00000008,
+ TreatAsSafe = 0x00000010,
+ }
+
+ // When the user calls AppDomain.DefineDynamicAssembly the loader creates a new InternalAssemblyBuilder.
+ // This InternalAssemblyBuilder can be retrieved via a call to Assembly.GetAssemblies() by untrusted code.
+ // In the past, when InternalAssemblyBuilder was AssemblyBuilder, the untrusted user could down cast the
+ // Assembly to an AssemblyBuilder and emit code with the elevated permissions of the trusted code which
+ // origionally created the AssemblyBuilder via DefineDynamicAssembly. Today, this can no longer happen
+ // because the Assembly returned via AssemblyGetAssemblies() will be an InternalAssemblyBuilder.
+
+ // Only the caller of DefineDynamicAssembly will get an AssemblyBuilder.
+ // There is a 1-1 relationship between InternalAssemblyBuilder and AssemblyBuilder.
+ // AssemblyBuilder is composed of its InternalAssemblyBuilder.
+ // The AssemblyBuilder data members (e.g. m_foo) were changed to properties which then delegate
+ // the access to the composed InternalAssemblyBuilder. This way, AssemblyBuilder simply wraps
+ // InternalAssemblyBuilder and still operates on InternalAssemblyBuilder members.
+ // This also makes the change transparent to the loader. This is good because most of the complexity
+ // of Assembly building is in the loader code so not touching that code reduces the chance of
+ // introducing new bugs.
+ internal sealed class InternalAssemblyBuilder : RuntimeAssembly
+ {
+ private InternalAssemblyBuilder() { }
+
+ #region object overrides
+ public override bool Equals(object obj)
+ {
+ if (obj == null)
+ return false;
+
+ if (obj is InternalAssemblyBuilder)
+ return ((object)this == obj);
+
+ return obj.Equals(this);
+ }
+ // Need a dummy GetHashCode to pair with Equals
+ public override int GetHashCode() { return base.GetHashCode(); }
+ #endregion
+
+ // Assembly methods that are overridden by AssemblyBuilder should be overridden by InternalAssemblyBuilder too
+ #region Methods inherited from Assembly
+ public override String[] GetManifestResourceNames()
+ {
+ throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicAssembly"));
+ }
+
+ #if FEATURE_CORECLR
+ [System.Security.SecurityCritical] // auto-generated
+ #endif
+ public override FileStream GetFile(String name)
+ {
+ throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicAssembly"));
+ }
+
+ #if FEATURE_CORECLR
+ [System.Security.SecurityCritical] // auto-generated
+ #endif
+ public override FileStream[] GetFiles(bool getResourceModules)
+ {
+ throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicAssembly"));
+ }
+
+ public override Stream GetManifestResourceStream(Type type, String name)
+ {
+ throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicAssembly"));
+ }
+
+ public override Stream GetManifestResourceStream(String name)
+ {
+ throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicAssembly"));
+ }
+
+ public override ManifestResourceInfo GetManifestResourceInfo(String resourceName)
+ {
+ throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicAssembly"));
+ }
+
+ public override String Location
+ {
+#if FEATURE_CORECLR
+ [SecurityCritical]
+#endif // FEATURE_CORECLR
+ get
+ {
+ throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicAssembly"));
+ }
+ }
+
+ public override String CodeBase
+ {
+#if FEATURE_CORECLR
+ [SecurityCritical]
+#endif // FEATURE_CORECLR
+ get
+ {
+ throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicAssembly"));
+ }
+ }
+
+ public override Type[] GetExportedTypes()
+ {
+ throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicAssembly"));
+ }
+
+ public override String ImageRuntimeVersion
+ {
+ get
+ {
+ return RuntimeEnvironment.GetSystemVersion();
+ }
+ }
+ #endregion
+ }
+
+ // AssemblyBuilder class.
+ // deliberately not [serializable]
+ [HostProtection(MayLeakOnAbort = true)]
+ [ClassInterface(ClassInterfaceType.None)]
+ [ComDefaultInterface(typeof(_AssemblyBuilder))]
+ [ComVisible(true)]
+ public sealed class AssemblyBuilder : Assembly, _AssemblyBuilder
+ {
+ #region FCALL
+ [System.Security.SecurityCritical] // auto-generated
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ private static extern RuntimeModule GetInMemoryAssemblyModule(RuntimeAssembly assembly);
+
+ [System.Security.SecurityCritical] // auto-generated
+ private Module nGetInMemoryAssemblyModule()
+ {
+ return AssemblyBuilder.GetInMemoryAssemblyModule(GetNativeHandle());
+ }
+
+#if !FEATURE_CORECLR
+ [System.Security.SecurityCritical] // auto-generated
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ private static extern RuntimeModule GetOnDiskAssemblyModule(RuntimeAssembly assembly);
+
+ [System.Security.SecurityCritical] // auto-generated
+ private ModuleBuilder GetOnDiskAssemblyModuleBuilder()
+ {
+ if (m_onDiskAssemblyModuleBuilder == null)
+ {
+ Module module = AssemblyBuilder.GetOnDiskAssemblyModule(InternalAssembly.GetNativeHandle());
+ ModuleBuilder modBuilder = new ModuleBuilder(this, (InternalModuleBuilder)module);
+ modBuilder.Init("RefEmit_OnDiskManifestModule", null, 0);
+ m_onDiskAssemblyModuleBuilder = modBuilder;
+ }
+
+ return m_onDiskAssemblyModuleBuilder;
+ }
+#endif // FEATURE_CORECLR
+
+ #endregion
+
+ #region Internal Data Members
+ // This is only valid in the "external" AssemblyBuilder
+ internal AssemblyBuilderData m_assemblyData;
+ private InternalAssemblyBuilder m_internalAssemblyBuilder;
+ private ModuleBuilder m_manifestModuleBuilder;
+ // Set to true if the manifest module was returned by code:DefineDynamicModule to the user
+ private bool m_fManifestModuleUsedAsDefinedModule;
+ internal const string MANIFEST_MODULE_NAME = "RefEmit_InMemoryManifestModule";
+#if !FEATURE_CORECLR
+ private ModuleBuilder m_onDiskAssemblyModuleBuilder;
+#endif // !FEATURE_CORECLR
+
+#if FEATURE_APPX
+ private bool m_profileAPICheck;
+#endif
+
+ internal ModuleBuilder GetModuleBuilder(InternalModuleBuilder module)
+ {
+ Contract.Requires(module != null);
+ Contract.Assert(this.InternalAssembly == module.Assembly);
+
+ lock(SyncRoot)
+ {
+#if !FEATURE_CORECLR
+ foreach (ModuleBuilder modBuilder in m_assemblyData.m_moduleBuilderList)
+ {
+ if (modBuilder.InternalModule == module)
+ return modBuilder;
+ }
+
+ // m_onDiskAssemblyModuleBuilder is null before Save
+ if (m_onDiskAssemblyModuleBuilder != null && m_onDiskAssemblyModuleBuilder.InternalModule == module)
+ return m_onDiskAssemblyModuleBuilder;
+#endif // !FEATURE_CORECLR
+
+ // in CoreCLR there is only one module in each dynamic assembly, the manifest module
+ if (m_manifestModuleBuilder.InternalModule == module)
+ return m_manifestModuleBuilder;
+
+ throw new ArgumentException("module");
+ }
+ }
+
+ internal object SyncRoot
+ {
+ get
+ {
+ return InternalAssembly.SyncRoot;
+ }
+ }
+
+ internal InternalAssemblyBuilder InternalAssembly
+ {
+ get
+ {
+ return m_internalAssemblyBuilder;
+ }
+ }
+
+ internal RuntimeAssembly GetNativeHandle()
+ {
+ return InternalAssembly.GetNativeHandle();
+ }
+
+ [SecurityCritical]
+ internal Version GetVersion()
+ {
+ return InternalAssembly.GetVersion();
+ }
+
+#if FEATURE_APPX
+ internal bool ProfileAPICheck
+ {
+ get
+ {
+ return m_profileAPICheck;
+ }
+ }
+#endif
+ #endregion
+
+ #region Constructor
+ [System.Security.SecurityCritical] // auto-generated
+ internal AssemblyBuilder(AppDomain domain,
+ AssemblyName name,
+ AssemblyBuilderAccess access,
+ String dir,
+ Evidence evidence,
+ PermissionSet requiredPermissions,
+ PermissionSet optionalPermissions,
+ PermissionSet refusedPermissions,
+ ref StackCrawlMark stackMark,
+ IEnumerable<CustomAttributeBuilder> unsafeAssemblyAttributes,
+ SecurityContextSource securityContextSource)
+ {
+ if (name == null)
+ throw new ArgumentNullException("name");
+
+ if (access != AssemblyBuilderAccess.Run
+#if !FEATURE_CORECLR
+ && access != AssemblyBuilderAccess.Save
+ && access != AssemblyBuilderAccess.RunAndSave
+#endif // !FEATURE_CORECLR
+#if FEATURE_REFLECTION_ONLY_LOAD
+ && access != AssemblyBuilderAccess.ReflectionOnly
+#endif // FEATURE_REFLECTION_ONLY_LOAD
+#if FEATURE_COLLECTIBLE_TYPES
+ && access != AssemblyBuilderAccess.RunAndCollect
+#endif // FEATURE_COLLECTIBLE_TYPES
+ )
+ {
+ throw new ArgumentException(Environment.GetResourceString("Arg_EnumIllegalVal", (int)access), "access");
+ }
+
+ if (securityContextSource < SecurityContextSource.CurrentAppDomain ||
+ securityContextSource > SecurityContextSource.CurrentAssembly)
+ {
+ throw new ArgumentOutOfRangeException("securityContextSource");
+ }
+
+ // Clone the name in case the caller modifies it underneath us.
+ name = (AssemblyName)name.Clone();
+
+#if !FEATURE_CORECLR
+ // Set the public key from the key pair if one has been provided.
+ // (Overwite any public key in the Assembly name, since it's no
+ // longer valid to have a disparity).
+ if (name.KeyPair != null)
+ name.SetPublicKey(name.KeyPair.PublicKey);
+#endif
+
+ // If the caller is trusted they can supply identity
+ // evidence for the new assembly. Otherwise we copy the
+ // current grant and deny sets from the caller's assembly,
+ // inject them into the new assembly and mark policy as
+ // resolved. If/when the assembly is persisted and
+ // reloaded, the normal rules for gathering evidence will
+ // be used.
+ if (evidence != null)
+#pragma warning disable 618
+ new SecurityPermission(SecurityPermissionFlag.ControlEvidence).Demand();
+#pragma warning restore 618
+
+#if FEATURE_COLLECTIBLE_TYPES && !FEATURE_CORECLR
+ // Collectible assemblies require FullTrust. This demand may be removed if we deem the
+ // feature robust enough to be used directly by untrusted API consumers.
+ if (access == AssemblyBuilderAccess.RunAndCollect)
+ new PermissionSet(PermissionState.Unrestricted).Demand();
+#endif // FEATURE_COLLECTIBLE_TYPES && !FEATURE_CORECLR
+
+ // Scan the assembly level attributes for any attributes which modify how we create the
+ // assembly. Currently, we look for any attribute which modifies the security transparency
+ // of the assembly.
+ List<CustomAttributeBuilder> assemblyAttributes = null;
+ DynamicAssemblyFlags assemblyFlags = DynamicAssemblyFlags.None;
+ byte[] securityRulesBlob = null;
+ byte[] aptcaBlob = null;
+ if (unsafeAssemblyAttributes != null)
+ {
+ // Create a copy to ensure that it cannot be modified from another thread
+ // as it is used further below.
+ assemblyAttributes = new List<CustomAttributeBuilder>(unsafeAssemblyAttributes);
+
+#pragma warning disable 618 // We deal with legacy attributes here as well for compat
+ foreach (CustomAttributeBuilder attribute in assemblyAttributes)
+ {
+ if (attribute.m_con.DeclaringType == typeof(SecurityTransparentAttribute))
+ {
+ assemblyFlags |= DynamicAssemblyFlags.Transparent;
+ }
+ else if (attribute.m_con.DeclaringType == typeof(SecurityCriticalAttribute))
+ {
+#if !FEATURE_CORECLR
+ SecurityCriticalScope scope = SecurityCriticalScope.Everything;
+ if (attribute.m_constructorArgs != null &&
+ attribute.m_constructorArgs.Length == 1 &&
+ attribute.m_constructorArgs[0] is SecurityCriticalScope)
+ {
+ scope = (SecurityCriticalScope)attribute.m_constructorArgs[0];
+ }
+
+ assemblyFlags |= DynamicAssemblyFlags.Critical;
+ if (scope == SecurityCriticalScope.Everything)
+#endif // !FEATURE_CORECLR
+ {
+ assemblyFlags |= DynamicAssemblyFlags.AllCritical;
+ }
+ }
+#if !FEATURE_CORECLR
+ else if (attribute.m_con.DeclaringType == typeof(SecurityRulesAttribute))
+ {
+ securityRulesBlob = new byte[attribute.m_blob.Length];
+ Buffer.BlockCopy(attribute.m_blob, 0, securityRulesBlob, 0, securityRulesBlob.Length);
+ }
+ else if (attribute.m_con.DeclaringType == typeof(SecurityTreatAsSafeAttribute))
+ {
+ assemblyFlags |= DynamicAssemblyFlags.TreatAsSafe;
+ }
+#endif // !FEATURE_CORECLR
+#if FEATURE_APTCA
+ else if (attribute.m_con.DeclaringType == typeof(AllowPartiallyTrustedCallersAttribute))
+ {
+ assemblyFlags |= DynamicAssemblyFlags.Aptca;
+ aptcaBlob = new byte[attribute.m_blob.Length];
+ Buffer.BlockCopy(attribute.m_blob, 0, aptcaBlob, 0, aptcaBlob.Length);
+ }
+#endif // FEATURE_APTCA
+ }
+#pragma warning restore 618
+ }
+
+ m_internalAssemblyBuilder = (InternalAssemblyBuilder)nCreateDynamicAssembly(domain,
+ name,
+ evidence,
+ ref stackMark,
+ requiredPermissions,
+ optionalPermissions,
+ refusedPermissions,
+ securityRulesBlob,
+ aptcaBlob,
+ access,
+ assemblyFlags,
+ securityContextSource);
+
+ m_assemblyData = new AssemblyBuilderData(m_internalAssemblyBuilder,
+ name.Name,
+ access,
+ dir);
+ m_assemblyData.AddPermissionRequests(requiredPermissions,
+ optionalPermissions,
+ refusedPermissions);
+
+#if FEATURE_APPX
+ if (AppDomain.ProfileAPICheck)
+ {
+ RuntimeAssembly creator = RuntimeAssembly.GetExecutingAssembly(ref stackMark);
+ if (creator != null && !creator.IsFrameworkAssembly())
+ m_profileAPICheck = true;
+ }
+#endif
+ // Make sure that ManifestModule is properly initialized
+ // We need to do this before setting any CustomAttribute
+ InitManifestModule();
+
+ if (assemblyAttributes != null)
+ {
+ foreach (CustomAttributeBuilder assemblyAttribute in assemblyAttributes)
+ SetCustomAttribute(assemblyAttribute);
+ }
+ }
+
+ [System.Security.SecurityCritical] // auto-generated
+ private void InitManifestModule()
+ {
+ InternalModuleBuilder modBuilder = (InternalModuleBuilder)nGetInMemoryAssemblyModule();
+
+ // Note that this ModuleBuilder cannot be used for RefEmit yet
+ // because it hasn't been initialized.
+ // However, it can be used to set the custom attribute on the Assembly
+ m_manifestModuleBuilder = new ModuleBuilder(this, modBuilder);
+
+ // We are only setting the name in the managed ModuleBuilderData here.
+ // The name in the underlying metadata will be set when the
+ // manifest module is created during nCreateDynamicAssembly.
+
+ // This name needs to stay in sync with that used in
+ // Assembly::Init to call ReflectionModule::Create (in VM)
+ m_manifestModuleBuilder.Init(AssemblyBuilder.MANIFEST_MODULE_NAME, null, 0);
+
+ m_fManifestModuleUsedAsDefinedModule = false;
+ }
+ #endregion
+
+ #region DefineDynamicAssembly
+
+ /**********************************************
+ * If an AssemblyName has a public key specified, the assembly is assumed
+ * to have a strong name and a hash will be computed when the assembly
+ * is saved.
+ **********************************************/
+ [System.Security.SecuritySafeCritical] // auto-generated
+ [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
+ public static AssemblyBuilder DefineDynamicAssembly(
+ AssemblyName name,
+ AssemblyBuilderAccess access)
+ {
+ Contract.Ensures(Contract.Result<AssemblyBuilder>() != null);
+
+ StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
+ return InternalDefineDynamicAssembly(name, access, null,
+ null, null, null, null, ref stackMark, null, SecurityContextSource.CurrentAssembly);
+ }
+
+ [System.Security.SecuritySafeCritical] // auto-generated
+ [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
+ public static AssemblyBuilder DefineDynamicAssembly(
+ AssemblyName name,
+ AssemblyBuilderAccess access,
+ IEnumerable<CustomAttributeBuilder> assemblyAttributes)
+ {
+ Contract.Ensures(Contract.Result<AssemblyBuilder>() != null);
+
+ StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
+ return InternalDefineDynamicAssembly(name,
+ access,
+ null, null, null, null, null,
+ ref stackMark,
+ assemblyAttributes, SecurityContextSource.CurrentAssembly);
+ }
+
+
+ [System.Security.SecurityCritical] // auto-generated
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ private static extern Assembly nCreateDynamicAssembly(AppDomain domain,
+ AssemblyName name,
+ Evidence identity,
+ ref StackCrawlMark stackMark,
+ PermissionSet requiredPermissions,
+ PermissionSet optionalPermissions,
+ PermissionSet refusedPermissions,
+ byte[] securityRulesBlob,
+ byte[] aptcaBlob,
+ AssemblyBuilderAccess access,
+ DynamicAssemblyFlags flags,
+ SecurityContextSource securityContextSource);
+
+ private class AssemblyBuilderLock { }
+
+ [System.Security.SecurityCritical] // auto-generated
+ internal static AssemblyBuilder InternalDefineDynamicAssembly(
+ AssemblyName name,
+ AssemblyBuilderAccess access,
+ String dir,
+ Evidence evidence,
+ PermissionSet requiredPermissions,
+ PermissionSet optionalPermissions,
+ PermissionSet refusedPermissions,
+ ref StackCrawlMark stackMark,
+ IEnumerable<CustomAttributeBuilder> unsafeAssemblyAttributes,
+ SecurityContextSource securityContextSource)
+ {
+#if FEATURE_CAS_POLICY
+ if (evidence != null && !AppDomain.CurrentDomain.IsLegacyCasPolicyEnabled)
+ {
+ throw new NotSupportedException(Environment.GetResourceString("NotSupported_RequiresCasPolicyExplicit"));
+ }
+#endif // FEATURE_CAS_POLICY
+
+ lock (typeof(AssemblyBuilderLock))
+ {
+ // we can only create dynamic assemblies in the current domain
+ return new AssemblyBuilder(AppDomain.CurrentDomain,
+ name,
+ access,
+ dir,
+ evidence,
+ requiredPermissions,
+ optionalPermissions,
+ refusedPermissions,
+ ref stackMark,
+ unsafeAssemblyAttributes,
+ securityContextSource);
+ } //lock(typeof(AssemblyBuilderLock))
+ }
+ #endregion
+
+ #region DefineDynamicModule
+ /**********************************************
+ *
+ * Defines a named dynamic module. It is an error to define multiple
+ * modules within an Assembly with the same name. This dynamic module is
+ * a transient module.
+ *
+ **********************************************/
+ [System.Security.SecuritySafeCritical] // auto-generated
+ [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
+ public ModuleBuilder DefineDynamicModule(
+ String name)
+ {
+ Contract.Ensures(Contract.Result<ModuleBuilder>() != null);
+
+ StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
+ return DefineDynamicModuleInternal(name, false, ref stackMark);
+ }
+
+ [System.Security.SecuritySafeCritical] // auto-generated
+ [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
+ public ModuleBuilder DefineDynamicModule(
+ String name,
+ bool emitSymbolInfo) // specify if emit symbol info or not
+ {
+ Contract.Ensures(Contract.Result<ModuleBuilder>() != null);
+
+ StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
+ return DefineDynamicModuleInternal( name, emitSymbolInfo, ref stackMark );
+ }
+
+ [System.Security.SecurityCritical] // auto-generated
+ private ModuleBuilder DefineDynamicModuleInternal(
+ String name,
+ bool emitSymbolInfo, // specify if emit symbol info or not
+ ref StackCrawlMark stackMark)
+ {
+ lock(SyncRoot)
+ {
+ return DefineDynamicModuleInternalNoLock(name, emitSymbolInfo, ref stackMark);
+ }
+ }
+
+ [System.Security.SecurityCritical] // auto-generated
+ private ModuleBuilder DefineDynamicModuleInternalNoLock(
+ String name,
+ bool emitSymbolInfo, // specify if emit symbol info or not
+ ref StackCrawlMark stackMark)
+ {
+ if (name == null)
+ throw new ArgumentNullException("name");
+ if (name.Length == 0)
+ throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), "name");
+ if (name[0] == '\0')
+ throw new ArgumentException(Environment.GetResourceString("Argument_InvalidName"), "name");
+ Contract.Ensures(Contract.Result<ModuleBuilder>() != null);
+ Contract.EndContractBlock();
+
+ BCLDebug.Log("DYNIL", "## DYNIL LOGGING: AssemblyBuilder.DefineDynamicModule( " + name + " )");
+
+ Contract.Assert(m_assemblyData != null, "m_assemblyData is null in DefineDynamicModuleInternal");
+
+ ModuleBuilder dynModule;
+ ISymbolWriter writer = null;
+ IntPtr pInternalSymWriter = new IntPtr();
+
+ // create the dynamic module
+
+#if FEATURE_MULTIMODULE_ASSEMBLIES
+
+#if FEATURE_CORECLR
+#error FEATURE_MULTIMODULE_ASSEMBLIES should always go with !FEATURE_CORECLR
+#endif //FEATURE_CORECLR
+
+ m_assemblyData.CheckNameConflict(name);
+
+ if (m_fManifestModuleUsedAsDefinedModule == true)
+ { // We need to define a new module
+ int tkFile;
+ InternalModuleBuilder internalDynModule = (InternalModuleBuilder)DefineDynamicModule(
+ InternalAssembly,
+ emitSymbolInfo,
+ name,
+ name,
+ ref stackMark,
+ ref pInternalSymWriter,
+ true /*fIsTransient*/,
+ out tkFile);
+ dynModule = new ModuleBuilder(this, internalDynModule);
+
+ // initialize the dynamic module's managed side information
+ dynModule.Init(name, null, tkFile);
+ }
+ else
+ { // We will reuse the manifest module
+ m_manifestModuleBuilder.ModifyModuleName(name);
+ dynModule = m_manifestModuleBuilder;
+
+ if (emitSymbolInfo)
+ {
+ pInternalSymWriter = ModuleBuilder.nCreateISymWriterForDynamicModule(dynModule.InternalModule, name);
+ }
+ }
+
+#else // FEATURE_MULTIMODULE_ASSEMBLIES
+ // Without FEATURE_MULTIMODULE_ASSEMBLIES only one ModuleBuilder per AssemblyBuilder can be created
+ if (m_fManifestModuleUsedAsDefinedModule == true)
+ throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NoMultiModuleAssembly"));
+
+ // Init(...) has already been called on m_manifestModuleBuilder in InitManifestModule()
+ dynModule = m_manifestModuleBuilder;
+#endif // FEATURE_MULTIMODULE_ASSEMBLIES
+
+ // Create the symbol writer
+ if (emitSymbolInfo)
+ {
+#if FEATURE_MULTIMODULE_ASSEMBLIES && !FEATURE_CORECLR
+ // this is the code path for the desktop runtime
+
+ // create the default SymWriter
+ Assembly assem = LoadISymWrapper();
+ Type symWriter = assem.GetType("System.Diagnostics.SymbolStore.SymWriter", true, false);
+ if (symWriter != null && !symWriter.IsVisible)
+ symWriter = null;
+
+ if (symWriter == null)
+ {
+ // cannot find SymWriter - throw TypeLoadException since we couldnt find the type.
+ throw new TypeLoadException(Environment.GetResourceString(ResId.MissingType, "SymWriter"));
+ }
+
+ new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand();
+
+ try
+ {
+ (new PermissionSet(PermissionState.Unrestricted)).Assert();
+ writer = (ISymbolWriter)Activator.CreateInstance(symWriter);
+
+ // Set the underlying writer for the managed writer
+ // that we're using. Note that this function requires
+ // unmanaged code access.
+ writer.SetUnderlyingWriter(pInternalSymWriter);
+ }
+ finally
+ {
+ CodeAccessPermission.RevertAssert();
+ }
+#endif // FEATURE_MULTIMODULE_ASSEMBLIES && !FEATURE_CORECLR
+
+#if !FEATURE_MULTIMODULE_ASSEMBLIES && FEATURE_CORECLR
+ // this is the code path for CoreCLR
+
+ writer = SymWrapperCore.SymWriter.CreateSymWriter();
+ // Set the underlying writer for the managed writer
+ // that we're using. Note that this function requires
+ // unmanaged code access.
+#pragma warning disable 618
+ new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Assert();
+#pragma warning restore 618
+
+ String fileName = "Unused"; // this symfile is never written to disk so filename does not matter.
+
+ // Pass the "real" module to the VM
+ pInternalSymWriter = ModuleBuilder.nCreateISymWriterForDynamicModule(dynModule.InternalModule, fileName);
+
+ // In Telesto, we took the SetUnderlyingWriter method private as it's a very rickety method.
+ // This might someday be a good move for the desktop CLR too.
+ ((SymWrapperCore.SymWriter)writer).InternalSetUnderlyingWriter(pInternalSymWriter);
+#endif // !FEATURE_MULTIMODULE_ASSEMBLIES && FEATURE_CORECLR
+ } // Creating the symbol writer
+
+ dynModule.SetSymWriter(writer);
+ m_assemblyData.AddModule(dynModule);
+
+ if (dynModule == m_manifestModuleBuilder)
+ { // We are reusing manifest module as user-defined dynamic module
+ m_fManifestModuleUsedAsDefinedModule = true;
+ }
+
+ return dynModule;
+ } // DefineDynamicModuleInternalNoLock
+
+#if !FEATURE_CORECLR
+ // All dynamic modules in SilverLight are transient so we removed this overload of DefineDynamicModule
+ // Note that it is assumed that !FEATURE_CORECLR always goes with FEATURE_MULTIMODULE_ASSEMBLIES
+ // If we ever will build a non coreclr version of the runtime without FEATURE_MULTIMODULE_ASSEMBLIES
+ // we will need to make the same changes here as the ones we made in the transient overload
+
+ /**********************************************
+ *
+ * Defines a named dynamic module. It is an error to define multiple
+ * modules within an Assembly with the same name. No symbol information
+ * will be emitted.
+ *
+ **********************************************/
+ [System.Security.SecuritySafeCritical] // auto-generated
+ [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
+ public ModuleBuilder DefineDynamicModule(
+ String name,
+ String fileName)
+ {
+ Contract.Ensures(Contract.Result<ModuleBuilder>() != null);
+
+ StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
+
+ // delegate to the next DefineDynamicModule
+ return DefineDynamicModuleInternal(name, fileName, false, ref stackMark);
+ }
+
+ /**********************************************
+ *
+ * Emit symbol information if emitSymbolInfo is true using the
+ * default symbol writer interface.
+ * An exception will be thrown if the assembly is transient.
+ *
+ **********************************************/
+ [System.Security.SecuritySafeCritical] // auto-generated
+ [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
+ public ModuleBuilder DefineDynamicModule(
+ String name, // module name
+ String fileName, // module file name
+ bool emitSymbolInfo) // specify if emit symbol info or not
+ {
+ Contract.Ensures(Contract.Result<ModuleBuilder>() != null);
+
+ StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
+ return DefineDynamicModuleInternal(name, fileName, emitSymbolInfo, ref stackMark);
+ }
+
+ [System.Security.SecurityCritical] // auto-generated
+ private ModuleBuilder DefineDynamicModuleInternal(
+ String name, // module name
+ String fileName, // module file name
+ bool emitSymbolInfo, // specify if emit symbol info or not
+ ref StackCrawlMark stackMark) // stack crawl mark used to find caller
+ {
+ lock(SyncRoot)
+ {
+ return DefineDynamicModuleInternalNoLock(name, fileName, emitSymbolInfo, ref stackMark);
+ }
+ }
+
+ // "name" will be used for:
+ // 1. The Name field in the Module table.
+ // 2. ModuleBuilder.GetModule(string).
+ // "fileName" will be used for:
+ // 1. The name field in the ModuleRef table when this module is being referenced by
+ // another module in the same assembly.
+ // 2. .file record in the in memory assembly manifest when the module is created in memory
+ // 3. .file record in the on disk assembly manifest when the assembly is saved to disk
+ // 4. The file name of the saved module.
+ [System.Security.SecurityCritical] // auto-generated
+ private ModuleBuilder DefineDynamicModuleInternalNoLock(
+ String name, // module name
+ String fileName, // module file name
+ bool emitSymbolInfo, // specify if emit symbol info or not
+ ref StackCrawlMark stackMark) // stack crawl mark used to find caller
+ {
+ if (name == null)
+ throw new ArgumentNullException("name");
+ if (name.Length == 0)
+ throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), "name");
+ if (name[0] == '\0')
+ throw new ArgumentException(Environment.GetResourceString("Argument_InvalidName"), "name");
+
+ if (fileName == null)
+ throw new ArgumentNullException("fileName");
+ if (fileName.Length == 0)
+ throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), "fileName");
+ if (!String.Equals(fileName, Path.GetFileName(fileName)))
+ throw new ArgumentException(Environment.GetResourceString("Argument_NotSimpleFileName"), "fileName");
+ Contract.Ensures(Contract.Result<ModuleBuilder>() != null);
+ Contract.EndContractBlock();
+
+ BCLDebug.Log("DYNIL", "## DYNIL LOGGING: AssemblyBuilder.DefineDynamicModule( " + name + ", " + fileName + ", " + emitSymbolInfo + " )");
+ if (m_assemblyData.m_access == AssemblyBuilderAccess.Run)
+ {
+ // Error! You cannot define a persistable module within a transient data.
+ throw new NotSupportedException(Environment.GetResourceString("Argument_BadPersistableModuleInTransientAssembly"));
+ }
+
+ if (m_assemblyData.m_isSaved == true)
+ {
+ // assembly has been saved before!
+ throw new InvalidOperationException(Environment.GetResourceString(
+ "InvalidOperation_CannotAlterAssembly"));
+ }
+
+ ModuleBuilder dynModule;
+ ISymbolWriter writer = null;
+ IntPtr pInternalSymWriter = new IntPtr();
+
+ // create the dynamic module
+
+ m_assemblyData.CheckNameConflict(name);
+ m_assemblyData.CheckFileNameConflict(fileName);
+
+ int tkFile;
+ InternalModuleBuilder internalDynModule = (InternalModuleBuilder)DefineDynamicModule(
+ InternalAssembly,
+ emitSymbolInfo,
+ name,
+ fileName,
+ ref stackMark,
+ ref pInternalSymWriter,
+ false /*fIsTransient*/,
+ out tkFile);
+ dynModule = new ModuleBuilder(this, internalDynModule);
+
+ // initialize the dynamic module's managed side information
+ dynModule.Init(name, fileName, tkFile);
+
+ // Create the symbol writer
+ if (emitSymbolInfo)
+ {
+ // create the default SymWriter
+ Assembly assem = LoadISymWrapper();
+ Type symWriter = assem.GetType("System.Diagnostics.SymbolStore.SymWriter", true, false);
+ if (symWriter != null && !symWriter.IsVisible)
+ symWriter = null;
+
+ if (symWriter == null)
+ {
+ // cannot find SymWriter - throw TypeLoadException since we couldnt find the type.
+ throw new TypeLoadException(Environment.GetResourceString("MissingType", "SymWriter"));
+ }
+ try
+ {
+ (new PermissionSet(PermissionState.Unrestricted)).Assert();
+ writer = (ISymbolWriter)Activator.CreateInstance(symWriter);
+
+ // Set the underlying writer for the managed writer
+ // that we're using. Note that this function requires
+ // unmanaged code access.
+ writer.SetUnderlyingWriter(pInternalSymWriter);
+ }
+ finally
+ {
+ CodeAccessPermission.RevertAssert();
+ }
+ }
+
+ dynModule.SetSymWriter(writer);
+
+ m_assemblyData.AddModule(dynModule);
+
+ return dynModule;
+ } // DefineDynamicModuleInternalNoLock
+#endif // !FEATURE_CORECLR
+ #endregion
+
+ private Assembly LoadISymWrapper()
+ {
+ if (m_assemblyData.m_ISymWrapperAssembly != null)
+ return m_assemblyData.m_ISymWrapperAssembly;
+
+ Assembly assem = Assembly.Load("ISymWrapper, Version=" + ThisAssembly.Version +
+ ", Culture=neutral, PublicKeyToken=" + AssemblyRef.MicrosoftPublicKeyToken);
+
+ m_assemblyData.m_ISymWrapperAssembly = assem;
+ return assem;
+ }
+
+ internal void CheckContext(params Type[][] typess)
+ {
+ if (typess == null)
+ return;
+
+ foreach(Type[] types in typess)
+ if (types != null)
+ CheckContext(types);
+ }
+
+ internal void CheckContext(params Type[] types)
+ {
+ if (types == null)
+ return;
+
+ foreach (Type type in types)
+ {
+ if (type == null)
+ continue;
+
+ if (type.Module == null || type.Module.Assembly == null)
+ throw new ArgumentException(Environment.GetResourceString("Argument_TypeNotValid"));
+
+ if (type.Module.Assembly == typeof(object).Module.Assembly)
+ continue;
+
+ if (type.Module.Assembly.ReflectionOnly && !ReflectionOnly)
+ throw new InvalidOperationException(Environment.GetResourceString("Arugment_EmitMixedContext1", type.AssemblyQualifiedName));
+
+ if (!type.Module.Assembly.ReflectionOnly && ReflectionOnly)
+ throw new InvalidOperationException(Environment.GetResourceString("Arugment_EmitMixedContext2", type.AssemblyQualifiedName));
+ }
+ }
+
+#if !FEATURE_CORECLR
+ /**********************************************
+ *
+ * Define stand alone managed resource for Assembly
+ *
+ **********************************************/
+ public IResourceWriter DefineResource(
+ String name,
+ String description,
+ String fileName)
+ {
+ return DefineResource(name, description, fileName, ResourceAttributes.Public);
+ }
+
+ /**********************************************
+ *
+ * Define stand alone managed resource for Assembly
+ *
+ **********************************************/
+ public IResourceWriter DefineResource(
+ String name,
+ String description,
+ String fileName,
+ ResourceAttributes attribute)
+ {
+ lock(SyncRoot)
+ {
+ return DefineResourceNoLock(name, description, fileName, attribute);
+ }
+ }
+
+ private IResourceWriter DefineResourceNoLock(
+ String name,
+ String description,
+ String fileName,
+ ResourceAttributes attribute)
+ {
+ if (name == null)
+ throw new ArgumentNullException("name");
+ if (name.Length == 0)
+ throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), name);
+ if (fileName == null)
+ throw new ArgumentNullException("fileName");
+ if (fileName.Length == 0)
+ throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), "fileName");
+ if (!String.Equals(fileName, Path.GetFileName(fileName)))
+ throw new ArgumentException(Environment.GetResourceString("Argument_NotSimpleFileName"), "fileName");
+ Contract.EndContractBlock();
+
+ BCLDebug.Log("DYNIL", "## DYNIL LOGGING: AssemblyBuilder.DefineResource( " + name + ", " + fileName + ")");
+
+ m_assemblyData.CheckResNameConflict(name);
+ m_assemblyData.CheckFileNameConflict(fileName);
+
+ ResourceWriter resWriter;
+ String fullFileName;
+
+ if (m_assemblyData.m_strDir == null)
+ {
+ // If assembly directory is null, use current directory
+ fullFileName = Path.Combine(Directory.GetCurrentDirectory(), fileName);
+ resWriter = new ResourceWriter(fullFileName);
+ }
+ else
+ {
+ // Form the full path given the directory provided by user
+ fullFileName = Path.Combine(m_assemblyData.m_strDir, fileName);
+ resWriter = new ResourceWriter(fullFileName);
+ }
+ // get the full path
+ fullFileName = Path.GetFullPath(fullFileName);
+
+ // retrieve just the file name
+ fileName = Path.GetFileName(fullFileName);
+
+ m_assemblyData.AddResWriter( new ResWriterData( resWriter, null, name, fileName, fullFileName, attribute) );
+ return resWriter;
+ }
+
+#endif // !FEATURE_CORECLR
+
+ /**********************************************
+ *
+ * Add an existing resource file to the Assembly
+ *
+ **********************************************/
+ #if FEATURE_CORECLR
+ [System.Security.SecurityCritical] // auto-generated
+ #endif
+ public void AddResourceFile(
+ String name,
+ String fileName)
+ {
+ AddResourceFile(name, fileName, ResourceAttributes.Public);
+ }
+
+ /**********************************************
+ *
+ * Add an existing resource file to the Assembly
+ *
+ **********************************************/
+ #if FEATURE_CORECLR
+ [System.Security.SecurityCritical] // auto-generated
+ #endif
+ public void AddResourceFile(
+ String name,
+ String fileName,
+ ResourceAttributes attribute)
+ {
+ lock(SyncRoot)
+ {
+ AddResourceFileNoLock(name, fileName, attribute);
+ }
+ }
+
+ [System.Security.SecuritySafeCritical]
+ private void AddResourceFileNoLock(
+ String name,
+ String fileName,
+ ResourceAttributes attribute)
+ {
+ if (name == null)
+ throw new ArgumentNullException("name");
+ if (name.Length == 0)
+ throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), name);
+ if (fileName == null)
+ throw new ArgumentNullException("fileName");
+ if (fileName.Length == 0)
+ throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), fileName);
+ if (!String.Equals(fileName, Path.GetFileName(fileName)))
+ throw new ArgumentException(Environment.GetResourceString("Argument_NotSimpleFileName"), "fileName");
+ Contract.EndContractBlock();
+
+ BCLDebug.Log("DYNIL", "## DYNIL LOGGING: AssemblyBuilder.AddResourceFile( " + name + ", " + fileName + ")");
+
+ m_assemblyData.CheckResNameConflict(name);
+ m_assemblyData.CheckFileNameConflict(fileName);
+
+ String fullFileName;
+
+ if (m_assemblyData.m_strDir == null)
+ {
+ // If assembly directory is null, use current directory
+ fullFileName = Path.Combine(Directory.GetCurrentDirectory(), fileName);
+ }
+ else
+ {
+ // Form the full path given the directory provided by user
+ fullFileName = Path.Combine(m_assemblyData.m_strDir, fileName);
+ }
+
+ // get the full path
+ fullFileName = Path.UnsafeGetFullPath(fullFileName);
+
+ // retrieve just the file name
+ fileName = Path.GetFileName(fullFileName);
+
+ if (File.UnsafeExists(fullFileName) == false)
+ throw new FileNotFoundException(Environment.GetResourceString(
+ "IO.FileNotFound_FileName",
+ fileName), fileName);
+ m_assemblyData.AddResWriter( new ResWriterData( null, null, name, fileName, fullFileName, attribute) );
+ }
+
+ #region object overrides
+ public override bool Equals(object obj)
+ {
+ return InternalAssembly.Equals(obj);
+ }
+ // Need a dummy GetHashCode to pair with Equals
+ public override int GetHashCode() { return InternalAssembly.GetHashCode(); }
+ #endregion
+
+ #region ICustomAttributeProvider Members
+ public override Object[] GetCustomAttributes(bool inherit)
+ {
+ return InternalAssembly.GetCustomAttributes(inherit);
+ }
+
+ public override Object[] GetCustomAttributes(Type attributeType, bool inherit)
+ {
+ return InternalAssembly.GetCustomAttributes(attributeType, inherit);
+ }
+
+ public override bool IsDefined(Type attributeType, bool inherit)
+ {
+ return InternalAssembly.IsDefined(attributeType, inherit);
+ }
+
+ public override IList<CustomAttributeData> GetCustomAttributesData()
+ {
+ return InternalAssembly.GetCustomAttributesData();
+ }
+ #endregion
+
+ #region Assembly overrides
+ // Returns the names of all the resources
+ public override String[] GetManifestResourceNames()
+ {
+ return InternalAssembly.GetManifestResourceNames();
+ }
+
+ #if FEATURE_CORECLR
+ [System.Security.SecurityCritical] // auto-generated
+ #endif
+ public override FileStream GetFile(String name)
+ {
+ return InternalAssembly.GetFile(name);
+ }
+
+ #if FEATURE_CORECLR
+ [System.Security.SecurityCritical] // auto-generated
+ #endif
+ public override FileStream[] GetFiles(bool getResourceModules)
+ {
+ return InternalAssembly.GetFiles(getResourceModules);
+ }
+
+ public override Stream GetManifestResourceStream(Type type, String name)
+ {
+ return InternalAssembly.GetManifestResourceStream(type, name);
+ }
+
+ public override Stream GetManifestResourceStream(String name)
+ {
+ return InternalAssembly.GetManifestResourceStream(name);
+ }
+
+ public override ManifestResourceInfo GetManifestResourceInfo(String resourceName)
+ {
+ return InternalAssembly.GetManifestResourceInfo(resourceName);
+ }
+
+ public override String Location
+ {
+ #if FEATURE_CORECLR
+ [System.Security.SecurityCritical] // auto-generated
+ #endif
+ get
+ {
+ return InternalAssembly.Location;
+ }
+ }
+
+ public override String ImageRuntimeVersion
+ {
+ get
+ {
+ return InternalAssembly.ImageRuntimeVersion;
+ }
+ }
+
+ public override String CodeBase
+ {
+ #if FEATURE_CORECLR
+ [System.Security.SecurityCritical] // auto-generated
+ #endif
+ get
+ {
+ return InternalAssembly.CodeBase;
+ }
+ }
+
+ // Override the EntryPoint method on Assembly.
+ // This doesn't need to be synchronized because it is simple enough
+ public override MethodInfo EntryPoint
+ {
+ get
+ {
+ return m_assemblyData.m_entryPointMethod;
+ }
+ }
+
+ // Get an array of all the public types defined in this assembly
+ public override Type[] GetExportedTypes()
+ {
+ return InternalAssembly.GetExportedTypes();
+ }
+
+ #if FEATURE_CORECLR
+ [System.Security.SecurityCritical] // auto-generated
+ #endif
+ public override AssemblyName GetName(bool copiedName)
+ {
+ return InternalAssembly.GetName(copiedName);
+ }
+
+ public override String FullName
+ {
+ get
+ {
+ return InternalAssembly.FullName;
+ }
+ }
+
+ public override Type GetType(String name, bool throwOnError, bool ignoreCase)
+ {
+ return InternalAssembly.GetType(name, throwOnError, ignoreCase);
+ }
+
+#if FEATURE_CAS_POLICY
+ public override Evidence Evidence
+ {
+ get
+ {
+ return InternalAssembly.Evidence;
+ }
+ }
+
+ public override PermissionSet PermissionSet
+ {
+ [SecurityCritical]
+ get
+ {
+ return InternalAssembly.PermissionSet;
+ }
+ }
+
+ public override SecurityRuleSet SecurityRuleSet
+ {
+ get
+ {
+ return InternalAssembly.SecurityRuleSet;
+ }
+ }
+#endif // FEATURE_CAS_POLICY
+
+ public override Module ManifestModule
+ {
+ get
+ {
+ return m_manifestModuleBuilder.InternalModule;
+ }
+ }
+
+ public override bool ReflectionOnly
+ {
+ get
+ {
+ return InternalAssembly.ReflectionOnly;
+ }
+ }
+
+ public override Module GetModule(String name)
+ {
+ return InternalAssembly.GetModule(name);
+ }
+
+ public override AssemblyName[] GetReferencedAssemblies()
+ {
+ return InternalAssembly.GetReferencedAssemblies();
+ }
+
+ public override bool GlobalAssemblyCache
+ {
+ get
+ {
+ return InternalAssembly.GlobalAssemblyCache;
+ }
+ }
+
+ public override Int64 HostContext
+ {
+ get
+ {
+ return InternalAssembly.HostContext;
+ }
+ }
+
+ public override Module[] GetModules(bool getResourceModules)
+ {
+ return InternalAssembly.GetModules(getResourceModules);
+ }
+
+ public override Module[] GetLoadedModules(bool getResourceModules)
+ {
+ return InternalAssembly.GetLoadedModules(getResourceModules);
+ }
+
+ [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
+ public override Assembly GetSatelliteAssembly(CultureInfo culture)
+ {
+ StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
+ return InternalAssembly.InternalGetSatelliteAssembly(culture, null, ref stackMark);
+ }
+
+ // Useful for binding to a very specific version of a satellite assembly
+ [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
+ public override Assembly GetSatelliteAssembly(CultureInfo culture, Version version)
+ {
+ StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
+ return InternalAssembly.InternalGetSatelliteAssembly(culture, version, ref stackMark);
+ }
+
+ public override bool IsDynamic
+ {
+ get {
+ return true;
+ }
+ }
+ #endregion
+
+
+ /**********************************************
+ *
+ * Add an unmanaged Version resource to the
+ * assembly
+ *
+ **********************************************/
+ public void DefineVersionInfoResource(
+ String product,
+ String productVersion,
+ String company,
+ String copyright,
+ String trademark)
+ {
+ lock(SyncRoot)
+ {
+ DefineVersionInfoResourceNoLock(
+ product,
+ productVersion,
+ company,
+ copyright,
+ trademark);
+ }
+ }
+
+ private void DefineVersionInfoResourceNoLock(
+ String product,
+ String productVersion,
+ String company,
+ String copyright,
+ String trademark)
+ {
+ if (m_assemblyData.m_strResourceFileName != null ||
+ m_assemblyData.m_resourceBytes != null ||
+ m_assemblyData.m_nativeVersion != null)
+ throw new ArgumentException(Environment.GetResourceString("Argument_NativeResourceAlreadyDefined"));
+
+ m_assemblyData.m_nativeVersion = new NativeVersionInfo();
+
+ m_assemblyData.m_nativeVersion.m_strCopyright = copyright;
+ m_assemblyData.m_nativeVersion.m_strTrademark = trademark;
+ m_assemblyData.m_nativeVersion.m_strCompany = company;
+ m_assemblyData.m_nativeVersion.m_strProduct = product;
+ m_assemblyData.m_nativeVersion.m_strProductVersion = productVersion;
+ m_assemblyData.m_hasUnmanagedVersionInfo = true;
+ m_assemblyData.m_OverrideUnmanagedVersionInfo = true;
+
+ }
+
+ public void DefineVersionInfoResource()
+ {
+ lock(SyncRoot)
+ {
+ DefineVersionInfoResourceNoLock();
+ }
+ }
+
+ private void DefineVersionInfoResourceNoLock()
+ {
+ if (m_assemblyData.m_strResourceFileName != null ||
+ m_assemblyData.m_resourceBytes != null ||
+ m_assemblyData.m_nativeVersion != null)
+ throw new ArgumentException(Environment.GetResourceString("Argument_NativeResourceAlreadyDefined"));
+
+ m_assemblyData.m_hasUnmanagedVersionInfo = true;
+ m_assemblyData.m_nativeVersion = new NativeVersionInfo();
+ }
+
+ public void DefineUnmanagedResource(Byte[] resource)
+ {
+ if (resource == null)
+ throw new ArgumentNullException("resource");
+ Contract.EndContractBlock();
+
+ lock(SyncRoot)
+ {
+ DefineUnmanagedResourceNoLock(resource);
+ }
+ }
+
+ private void DefineUnmanagedResourceNoLock(Byte[] resource)
+ {
+ if (m_assemblyData.m_strResourceFileName != null ||
+ m_assemblyData.m_resourceBytes != null ||
+ m_assemblyData.m_nativeVersion != null)
+ throw new ArgumentException(Environment.GetResourceString("Argument_NativeResourceAlreadyDefined"));
+
+ m_assemblyData.m_resourceBytes = new byte[resource.Length];
+ Buffer.BlockCopy(resource, 0, m_assemblyData.m_resourceBytes, 0, resource.Length);
+ }
+
+ [System.Security.SecuritySafeCritical] // auto-generated
+ public void DefineUnmanagedResource(String resourceFileName)
+ {
+ if (resourceFileName == null)
+ throw new ArgumentNullException("resourceFileName");
+ Contract.EndContractBlock();
+
+ lock(SyncRoot)
+ {
+ DefineUnmanagedResourceNoLock(resourceFileName);
+ }
+ }
+
+ [System.Security.SecurityCritical] // auto-generated
+ private void DefineUnmanagedResourceNoLock(String resourceFileName)
+ {
+ if (m_assemblyData.m_strResourceFileName != null ||
+ m_assemblyData.m_resourceBytes != null ||
+ m_assemblyData.m_nativeVersion != null)
+ throw new ArgumentException(Environment.GetResourceString("Argument_NativeResourceAlreadyDefined"));
+
+ // Check caller has the right to read the file.
+ string strFullFileName;
+ if (m_assemblyData.m_strDir == null)
+ {
+ // If assembly directory is null, use current directory
+ strFullFileName = Path.Combine(Directory.GetCurrentDirectory(), resourceFileName);
+ }
+ else
+ {
+ // Form the full path given the directory provided by user
+ strFullFileName = Path.Combine(m_assemblyData.m_strDir, resourceFileName);
+ }
+ strFullFileName = Path.GetFullPath(resourceFileName);
+ new FileIOPermission(FileIOPermissionAccess.Read, strFullFileName).Demand();
+
+ if (File.Exists(strFullFileName) == false)
+ throw new FileNotFoundException(Environment.GetResourceString(
+ "IO.FileNotFound_FileName",
+ resourceFileName), resourceFileName);
+ m_assemblyData.m_strResourceFileName = strFullFileName;
+ }
+
+
+
+ /**********************************************
+ *
+ * return a dynamic module with the specified name.
+ *
+ **********************************************/
+ public ModuleBuilder GetDynamicModule(
+ String name) // the name of module for the look up
+ {
+ lock(SyncRoot)
+ {
+ return GetDynamicModuleNoLock(name);
+ }
+ }
+
+ private ModuleBuilder GetDynamicModuleNoLock(
+ String name) // the name of module for the look up
+ {
+ if (name == null)
+ throw new ArgumentNullException("name");
+ if (name.Length == 0)
+ throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), "name");
+ Contract.EndContractBlock();
+
+ BCLDebug.Log("DYNIL", "## DYNIL LOGGING: AssemblyBuilder.GetDynamicModule( " + name + " )");
+ int size = m_assemblyData.m_moduleBuilderList.Count;
+ for (int i = 0; i < size; i++)
+ {
+ ModuleBuilder moduleBuilder = (ModuleBuilder) m_assemblyData.m_moduleBuilderList[i];
+ if (moduleBuilder.m_moduleData.m_strModuleName.Equals(name))
+ {
+ return moduleBuilder;
+ }
+ }
+ return null;
+ }
+
+ /**********************************************
+ *
+ * Setting the entry point if the assembly builder is building
+ * an exe.
+ *
+ **********************************************/
+ #if FEATURE_CORECLR
+ [System.Security.SecurityCritical] // auto-generated
+ #endif
+ public void SetEntryPoint(
+ MethodInfo entryMethod)
+ {
+ SetEntryPoint(entryMethod, PEFileKinds.ConsoleApplication);
+ }
+ #if FEATURE_CORECLR
+ [System.Security.SecurityCritical] // auto-generated
+ #endif
+ public void SetEntryPoint(
+ MethodInfo entryMethod, // entry method for the assembly. We use this to determine the entry module
+ PEFileKinds fileKind) // file kind for the assembly.
+ {
+ lock(SyncRoot)
+ {
+ SetEntryPointNoLock(entryMethod, fileKind);
+ }
+ }
+
+ private void SetEntryPointNoLock(
+ MethodInfo entryMethod, // entry method for the assembly. We use this to determine the entry module
+ PEFileKinds fileKind) // file kind for the assembly.
+ {
+
+ if (entryMethod == null)
+ throw new ArgumentNullException("entryMethod");
+ Contract.EndContractBlock();
+
+ BCLDebug.Log("DYNIL", "## DYNIL LOGGING: AssemblyBuilder.SetEntryPoint");
+
+ Module tmpModule = entryMethod.Module;
+ if (tmpModule == null || !InternalAssembly.Equals(tmpModule.Assembly))
+ throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_EntryMethodNotDefinedInAssembly"));
+
+ m_assemblyData.m_entryPointMethod = entryMethod;
+ m_assemblyData.m_peFileKind = fileKind;
+
+#if !FEATURE_CORECLR
+ // Setting the entry point
+ ModuleBuilder tmpMB = tmpModule as ModuleBuilder;
+ if (tmpMB != null)
+ m_assemblyData.m_entryPointModule = tmpMB;
+ else
+ m_assemblyData.m_entryPointModule = GetModuleBuilder((InternalModuleBuilder)tmpModule);
+
+ MethodToken entryMethodToken = m_assemblyData.m_entryPointModule.GetMethodToken(entryMethod);
+ m_assemblyData.m_entryPointModule.SetEntryPoint(entryMethodToken);
+#endif //!FEATURE_CORECLR
+ }
+
+
+ /**********************************************
+ * Use this function if client decides to form the custom attribute blob themselves
+ **********************************************/
+ #if FEATURE_CORECLR
+ [System.Security.SecurityCritical] // auto-generated
+ #else
+ [System.Security.SecuritySafeCritical]
+ #endif
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute)
+ {
+ if (con == null)
+ throw new ArgumentNullException("con");
+ if (binaryAttribute == null)
+ throw new ArgumentNullException("binaryAttribute");
+ Contract.EndContractBlock();
+
+ lock(SyncRoot)
+ {
+ SetCustomAttributeNoLock(con, binaryAttribute);
+ }
+ }
+
+ [System.Security.SecurityCritical] // auto-generated
+ private void SetCustomAttributeNoLock(ConstructorInfo con, byte[] binaryAttribute)
+ {
+ TypeBuilder.DefineCustomAttribute(
+ m_manifestModuleBuilder, // pass in the in-memory assembly module
+ AssemblyBuilderData.m_tkAssembly, // This is the AssemblyDef token
+ m_manifestModuleBuilder.GetConstructorToken(con).Token,
+ binaryAttribute,
+ false,
+ typeof(System.Diagnostics.DebuggableAttribute) == con.DeclaringType);
+
+ // Track the CA for persistence
+ if (m_assemblyData.m_access != AssemblyBuilderAccess.Run)
+ {
+ // tracking the CAs for persistence
+ m_assemblyData.AddCustomAttribute(con, binaryAttribute);
+ }
+ }
+
+ /**********************************************
+ * Use this function if client wishes to build CustomAttribute using CustomAttributeBuilder
+ **********************************************/
+ [System.Security.SecuritySafeCritical] // auto-generated
+ public void SetCustomAttribute(CustomAttributeBuilder customBuilder)
+ {
+ if (customBuilder == null)
+ {
+ throw new ArgumentNullException("customBuilder");
+ }
+ Contract.EndContractBlock();
+
+ lock(SyncRoot)
+ {
+ SetCustomAttributeNoLock(customBuilder);
+ }
+ }
+
+ [System.Security.SecurityCritical] // auto-generated
+ private void SetCustomAttributeNoLock(CustomAttributeBuilder customBuilder)
+ {
+ customBuilder.CreateCustomAttribute(
+ m_manifestModuleBuilder,
+ AssemblyBuilderData.m_tkAssembly); // This is the AssemblyDef token
+
+ // Track the CA for persistence
+ if (m_assemblyData.m_access != AssemblyBuilderAccess.Run)
+ {
+ m_assemblyData.AddCustomAttribute(customBuilder);
+ }
+ }
+
+
+ /**********************************************
+ *
+ * Saves the assembly to disk. Also saves all dynamic modules defined
+ * in this dynamic assembly. Assembly file name can be the same as one of
+ * the module's name. If so, assembly info is stored within that module.
+ * Assembly file name can be different from all of the modules underneath. In
+ * this case, assembly is stored stand alone.
+ *
+ **********************************************/
+
+ public void Save(String assemblyFileName) // assembly file name
+ {
+ Save(assemblyFileName, System.Reflection.PortableExecutableKinds.ILOnly, System.Reflection.ImageFileMachine.I386);
+ }
+
+ [System.Security.SecuritySafeCritical] // auto-generated
+ public void Save(String assemblyFileName,
+ PortableExecutableKinds portableExecutableKind, ImageFileMachine imageFileMachine)
+ {
+ lock(SyncRoot)
+ {
+ SaveNoLock(assemblyFileName, portableExecutableKind, imageFileMachine);
+ }
+ }
+
+#if FEATURE_CORECLR
+ private void SaveNoLock(String assemblyFileName,
+ PortableExecutableKinds portableExecutableKind, ImageFileMachine imageFileMachine)
+ {
+ // AssemblyBuilderAccess.Save can never be set with FEATURE_CORECLR
+ throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CantSaveTransientAssembly"));
+ }
+#else // FEATURE_CORECLR
+ [System.Security.SecurityCritical] // auto-generated
+ private void SaveNoLock(String assemblyFileName,
+ PortableExecutableKinds portableExecutableKind, ImageFileMachine imageFileMachine)
+ {
+ if (assemblyFileName == null)
+ throw new ArgumentNullException("assemblyFileName");
+ if (assemblyFileName.Length == 0)
+ throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), "assemblyFileName");
+ if (!String.Equals(assemblyFileName, Path.GetFileName(assemblyFileName)))
+ throw new ArgumentException(Environment.GetResourceString("Argument_NotSimpleFileName"), "assemblyFileName");
+ Contract.EndContractBlock();
+
+ int i;
+ int size;
+ Type type;
+ TypeBuilder typeBuilder;
+ ModuleBuilder modBuilder;
+ String strModFileName;
+ ModuleBuilder assemblyModule;
+ ResWriterData tempRes;
+ int[] tkAttrs = null;
+ int[] tkAttrs2 = null;
+ ModuleBuilder onDiskAssemblyModule;
+
+ BCLDebug.Log("DYNIL","## DYNIL LOGGING: AssemblyBuilder.Save( " + assemblyFileName + " )");
+
+ String tmpVersionFile = null;
+
+ try
+ {
+ if (m_assemblyData.m_iCABuilder != 0)
+ tkAttrs = new int[m_assemblyData.m_iCABuilder];
+ if ( m_assemblyData.m_iCAs != 0)
+ tkAttrs2 = new int[m_assemblyData.m_iCAs];
+
+ if (m_assemblyData.m_isSaved == true)
+ {
+ // assembly has been saved before!
+ throw new InvalidOperationException(Environment.GetResourceString(ResId.InvalidOperation_AssemblyHasBeenSaved,
+ InternalAssembly.GetSimpleName()));
+ }
+
+ if ((m_assemblyData.m_access & AssemblyBuilderAccess.Save) != AssemblyBuilderAccess.Save)
+ {
+ throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CantSaveTransientAssembly"));
+ }
+
+ // Check if assembly info is supposed to be stored with one of the module files.
+ assemblyModule = m_assemblyData.FindModuleWithFileName(assemblyFileName);
+
+ if (assemblyModule != null)
+ {
+ m_onDiskAssemblyModuleBuilder = assemblyModule;
+
+ // In memory this module is not the manifest module and has a valid file token
+ // On disk it will be the manifest module so lets clean the file token
+ // We should not retrieve FileToken after the assembly has been saved
+ // If that is absolutely necessary, we need two separate fields on ModuleBuilderData:
+ // the in memory file token and the on disk file token.
+ assemblyModule.m_moduleData.FileToken = 0;
+ }
+ else
+ { // If assembly is to be stored alone, then no file name should conflict with it.
+ // This check will ensure resource file names are different assembly file name.
+ m_assemblyData.CheckFileNameConflict(assemblyFileName);
+ }
+
+ if (m_assemblyData.m_strDir == null)
+ {
+ // set it to current directory
+ m_assemblyData.m_strDir = Directory.GetCurrentDirectory();
+ }
+ else if (Directory.Exists(m_assemblyData.m_strDir) == false)
+ {
+ throw new ArgumentException(Environment.GetResourceString("Argument_InvalidDirectory",
+ m_assemblyData.m_strDir));
+ }
+
+ // after this point, assemblyFileName is the full path name.
+ assemblyFileName = Path.Combine(m_assemblyData.m_strDir, assemblyFileName);
+ assemblyFileName = Path.GetFullPath(assemblyFileName);
+
+ // Check caller has the right to create the assembly file itself.
+ new FileIOPermission(FileIOPermissionAccess.Write | FileIOPermissionAccess.Append, assemblyFileName).Demand();
+
+ // 1. setup/create the IMetaDataAssemblyEmit for the on disk version
+ if (assemblyModule != null)
+ {
+ // prepare saving CAs on assembly def. We need to introduce the MemberRef for
+ // the CA's type first of all. This is for the case the we have embedded manifest.
+ // We need to introduce these MRs before we call PreSave where we will snap
+ // into a ondisk metadata. If we do it after this, the ondisk metadata will
+ // not contain the proper MRs.
+ //
+ for (i=0; i < m_assemblyData.m_iCABuilder; i++)
+ {
+ tkAttrs[i] = m_assemblyData.m_CABuilders[i].PrepareCreateCustomAttributeToDisk(
+ assemblyModule);
+ }
+ for (i=0; i < m_assemblyData.m_iCAs; i++)
+ {
+ tkAttrs2[i] = assemblyModule.InternalGetConstructorToken(m_assemblyData.m_CACons[i], true).Token;
+ }
+ assemblyModule.PreSave(assemblyFileName, portableExecutableKind, imageFileMachine);
+ }
+
+ RuntimeModule runtimeAssemblyModule = (assemblyModule != null) ? assemblyModule.ModuleHandle.GetRuntimeModule() : null;
+ PrepareForSavingManifestToDisk(GetNativeHandle(), runtimeAssemblyModule);
+
+ // This function will return the embedded manifest module, an already exposed ModuleBuilder
+ // created by user, or make the stand alone manifest module exposed through managed code.
+ //
+ onDiskAssemblyModule = GetOnDiskAssemblyModuleBuilder();
+
+ // Set any native resources on the OnDiskAssemblyModule.
+ if (m_assemblyData.m_strResourceFileName != null)
+ onDiskAssemblyModule.DefineUnmanagedResourceFileInternalNoLock(m_assemblyData.m_strResourceFileName);
+ else if (m_assemblyData.m_resourceBytes != null)
+ onDiskAssemblyModule.DefineUnmanagedResourceInternalNoLock(m_assemblyData.m_resourceBytes);
+ else if (m_assemblyData.m_hasUnmanagedVersionInfo == true)
+ {
+ // calculate unmanaged version info from assembly's custom attributes
+ m_assemblyData.FillUnmanagedVersionInfo();
+
+ String strFileVersion = m_assemblyData.m_nativeVersion.m_strFileVersion;
+ if (strFileVersion == null)
+ strFileVersion = GetVersion().ToString();
+
+ // Create the file.
+ CreateVersionInfoResource(
+ assemblyFileName,
+ m_assemblyData.m_nativeVersion.m_strTitle, // title
+ null, // Icon filename
+ m_assemblyData.m_nativeVersion.m_strDescription, // description
+ m_assemblyData.m_nativeVersion.m_strCopyright,
+ m_assemblyData.m_nativeVersion.m_strTrademark,
+ m_assemblyData.m_nativeVersion.m_strCompany,
+ m_assemblyData.m_nativeVersion.m_strProduct,
+ m_assemblyData.m_nativeVersion.m_strProductVersion,
+ strFileVersion,
+ m_assemblyData.m_nativeVersion.m_lcid,
+ m_assemblyData.m_peFileKind == PEFileKinds.Dll,
+ JitHelpers.GetStringHandleOnStack(ref tmpVersionFile));
+
+ onDiskAssemblyModule.DefineUnmanagedResourceFileInternalNoLock(tmpVersionFile);
+ }
+
+ if (assemblyModule == null)
+ {
+
+ // This is for introducing the MRs for CA's type. This case is for stand alone
+ // manifest. We need to wait till PrepareForSavingManifestToDisk is called.
+ // That will trigger the creation of the on-disk stand alone manifest module.
+ //
+ for (i=0; i < m_assemblyData.m_iCABuilder; i++)
+ {
+ tkAttrs[i] = m_assemblyData.m_CABuilders[i].PrepareCreateCustomAttributeToDisk(
+ onDiskAssemblyModule);
+ }
+ for (i=0; i < m_assemblyData.m_iCAs; i++)
+ {
+ tkAttrs2[i] = onDiskAssemblyModule.InternalGetConstructorToken(m_assemblyData.m_CACons[i], true).Token;
+ }
+ }
+
+ // 2. save all of the persistable modules contained by this AssemblyBuilder except the module that is going to contain
+ // Assembly information
+ //
+ // 3. create the file list in the manifest and track the file token. If it is embedded assembly,
+ // the assembly file should not be on the file list.
+ //
+ size = m_assemblyData.m_moduleBuilderList.Count;
+ for (i = 0; i < size; i++)
+ {
+ ModuleBuilder mBuilder = (ModuleBuilder) m_assemblyData.m_moduleBuilderList[i];
+ if (mBuilder.IsTransient() == false && mBuilder != assemblyModule)
+ {
+ strModFileName = mBuilder.m_moduleData.m_strFileName;
+ if (m_assemblyData.m_strDir != null)
+ {
+ strModFileName = Path.Combine(m_assemblyData.m_strDir, strModFileName);
+ strModFileName = Path.GetFullPath(strModFileName);
+ }
+
+ // Check caller has the right to create the Module file itself.
+ new FileIOPermission(FileIOPermissionAccess.Write | FileIOPermissionAccess.Append, strModFileName).Demand();
+
+ mBuilder.m_moduleData.FileToken = AddFile(GetNativeHandle(), mBuilder.m_moduleData.m_strFileName);
+ mBuilder.PreSave(strModFileName, portableExecutableKind, imageFileMachine);
+ mBuilder.Save(strModFileName, false, portableExecutableKind, imageFileMachine);
+
+ // Cannot set the hash value when creating the file since the file token
+ // is needed to created the entries for the embedded resources in the
+ // module and the resources need to be there before you figure the hash.
+ SetFileHashValue(GetNativeHandle(), mBuilder.m_moduleData.FileToken, strModFileName);
+ }
+ }
+
+ // 4. Add the public ComType
+ for (i=0; i < m_assemblyData.m_iPublicComTypeCount; i++)
+ {
+ type = m_assemblyData.m_publicComTypeList[i];
+ // If the type that was added as a Public Com Type was obtained via Reflection,
+ // it will be a System.RuntimeType, even if it was really, at the same time,
+ // a TypeBuilder. Unfortunately, you can't get back to the TypeBuilder, so
+ // this code has to deal with either-or.
+ if (type is RuntimeType)
+ {
+ // If type is a runtime type, it must be a baked TypeBuilder,
+ // ttype.Module should be an InternalModuleBuilder
+
+ InternalModuleBuilder internalMB = (InternalModuleBuilder)type.Module;
+ modBuilder = this.GetModuleBuilder(internalMB);
+ if (modBuilder != assemblyModule)
+ DefineNestedComType(type, modBuilder.m_moduleData.FileToken, type.MetadataToken);
+ }
+ else
+ {
+ // Could assert that "type" is a TypeBuilder, but next statement throws if it isn't.
+ typeBuilder = (TypeBuilder) type;
+ // If type is a TypeBuilder, type.Module must be a ModuleBuilder.
+ modBuilder = typeBuilder.GetModuleBuilder();
+ if (modBuilder != assemblyModule)
+ DefineNestedComType(type, modBuilder.m_moduleData.FileToken, typeBuilder.MetadataTokenInternal);
+ }
+ }
+
+ // 5. write AssemblyDef's CAs (only if we are not saving directly the manifest module itself)
+ if (onDiskAssemblyModule != m_manifestModuleBuilder)
+ {
+ for (i = 0; i < m_assemblyData.m_iCABuilder; i++)
+ {
+ m_assemblyData.m_CABuilders[i].CreateCustomAttribute(
+ onDiskAssemblyModule,
+ AssemblyBuilderData.m_tkAssembly, // This is the AssemblyDef token
+ tkAttrs[i], true);
+ }
+
+ for (i = 0; i < m_assemblyData.m_iCAs; i++)
+ {
+ TypeBuilder.DefineCustomAttribute(
+ onDiskAssemblyModule, // pass in the in-memory assembly module
+ AssemblyBuilderData.m_tkAssembly, // This is the AssemblyDef token
+ tkAttrs2[i],
+ m_assemblyData.m_CABytes[i],
+ true, false);
+ }
+ }
+
+ // 6. write security permission requests to the manifest.
+#pragma warning disable 618
+ if (m_assemblyData.m_RequiredPset != null)
+ AddDeclarativeSecurity(m_assemblyData.m_RequiredPset, SecurityAction.RequestMinimum);
+
+ if (m_assemblyData.m_RefusedPset != null)
+ AddDeclarativeSecurity(m_assemblyData.m_RefusedPset, SecurityAction.RequestRefuse);
+
+ if (m_assemblyData.m_OptionalPset != null)
+ AddDeclarativeSecurity(m_assemblyData.m_OptionalPset, SecurityAction.RequestOptional);
+#pragma warning restore 618
+
+ // 7. Save the stand alone managed resources
+ size = m_assemblyData.m_resWriterList.Count;
+ for (i = 0; i < size; i++)
+ {
+ tempRes = null;
+
+ try
+ {
+ tempRes = (ResWriterData)m_assemblyData.m_resWriterList[i];
+
+ // If the user added an existing resource to the manifest, the
+ // corresponding ResourceWriter will be null.
+ if (tempRes.m_resWriter != null)
+ // Check caller has the right to create the Resource file itself.
+ new FileIOPermission(FileIOPermissionAccess.Write | FileIOPermissionAccess.Append, tempRes.m_strFullFileName).Demand();
+ }
+ finally
+ {
+ if (tempRes != null && tempRes.m_resWriter != null)
+ tempRes.m_resWriter.Close();
+ }
+
+ // Add entry to manifest for this stand alone resource
+ AddStandAloneResource(GetNativeHandle(), tempRes.m_strName, tempRes.m_strFileName, tempRes.m_strFullFileName, (int)tempRes.m_attribute);
+ }
+
+ // Save now!!
+ if (assemblyModule == null)
+ {
+ onDiskAssemblyModule.DefineNativeResource(portableExecutableKind, imageFileMachine);
+
+ // Stand alone manifest
+ int entryPoint = (m_assemblyData.m_entryPointModule != null) ? m_assemblyData.m_entryPointModule.m_moduleData.FileToken : 0;
+
+ SaveManifestToDisk(GetNativeHandle(), assemblyFileName, entryPoint, (int)m_assemblyData.m_peFileKind,
+ (int)portableExecutableKind, (int)imageFileMachine);
+ }
+ else
+ {
+ // embedded manifest
+
+ // If the module containing the entry point is not the manifest file, we need to
+ // let the manifest file point to the module which contains the entry point.
+ //
+ //
+ //
+ //
+ if (m_assemblyData.m_entryPointModule != null && m_assemblyData.m_entryPointModule != assemblyModule)
+ assemblyModule.SetEntryPoint(new MethodToken(m_assemblyData.m_entryPointModule.m_moduleData.FileToken));
+ assemblyModule.Save(assemblyFileName, true, portableExecutableKind, imageFileMachine);
+ }
+ m_assemblyData.m_isSaved = true;
+ }
+ finally
+ {
+ if (tmpVersionFile != null)
+ {
+ // Delete file.
+ System.IO.File.Delete(tmpVersionFile);
+ }
+ }
+ }
+#endif // FEATURE_CORECLR
+
+#if FEATURE_CAS_POLICY
+ [System.Security.SecurityCritical] // auto-generated
+ private void AddDeclarativeSecurity(PermissionSet pset, SecurityAction action)
+ {
+ // Translate sets into internal encoding (uses standard binary serialization).
+ byte[] blob = pset.EncodeXml();
+ AddDeclarativeSecurity(GetNativeHandle(), action, blob, blob.Length);
+ }
+#endif // FEATURE_CAS_POLICY
+
+ internal bool IsPersistable()
+ {
+#if !FEATURE_CORECLR // AssemblyBuilderAccess.Save is never set in CoreCLR
+ if ((m_assemblyData.m_access & AssemblyBuilderAccess.Save) == AssemblyBuilderAccess.Save)
+ {
+ return true;
+ }
+ else
+#endif // FEATURE_CORECLR
+ {
+ return false;
+ }
+ }
+
+ /**********************************************
+ *
+ * Internal helper to walk the nested type hierachy
+ *
+ **********************************************/
+ [System.Security.SecurityCritical] // auto-generated
+ private int DefineNestedComType(Type type, int tkResolutionScope, int tkTypeDef)
+ {
+ Type enclosingType = type.DeclaringType;
+ if (enclosingType == null)
+ {
+ // Use full type name for non-nested types.
+ return AddExportedTypeOnDisk(GetNativeHandle(), type.FullName, tkResolutionScope, tkTypeDef, type.Attributes);
+ }
+
+ tkResolutionScope = DefineNestedComType(enclosingType, tkResolutionScope, tkTypeDef);
+ // Use simple name for nested types.
+ return AddExportedTypeOnDisk(GetNativeHandle(), type.Name, tkResolutionScope, tkTypeDef, type.Attributes);
+ }
+
+ [System.Security.SecurityCritical] // auto-generated
+ internal int DefineExportedTypeInMemory(Type type, int tkResolutionScope, int tkTypeDef)
+ {
+ Type enclosingType = type.DeclaringType;
+ if (enclosingType == null)
+ {
+ // Use full type name for non-nested types.
+ return AddExportedTypeInMemory(GetNativeHandle(), type.FullName, tkResolutionScope, tkTypeDef, type.Attributes);
+ }
+
+ tkResolutionScope = DefineExportedTypeInMemory(enclosingType, tkResolutionScope, tkTypeDef);
+ // Use simple name for nested types.
+ return AddExportedTypeInMemory(GetNativeHandle(), type.Name, tkResolutionScope, tkTypeDef, type.Attributes);
+ }
+
+ /**********************************************
+ *
+ * Private methods
+ *
+ **********************************************/
+
+ /**********************************************
+ * Make a private constructor so these cannot be constructed externally.
+ * @internonly
+ **********************************************/
+ private AssemblyBuilder() {}
+
+#if !FEATURE_CORECLR
+ void _AssemblyBuilder.GetTypeInfoCount(out uint pcTInfo)
+ {
+ throw new NotImplementedException();
+ }
+
+ void _AssemblyBuilder.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo)
+ {
+ throw new NotImplementedException();
+ }
+
+ void _AssemblyBuilder.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
+ {
+ throw new NotImplementedException();
+ }
+
+ // If you implement this method, make sure to include _AssemblyBuilder.Invoke in VM\DangerousAPIs.h and
+ // include _AssemblyBuilder in SystemDomain::IsReflectionInvocationMethod in AppDomain.cpp.
+ void _AssemblyBuilder.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
+ {
+ throw new NotImplementedException();
+ }
+#endif
+
+ // Create a new module in which to emit code. This module will not contain the manifest.
+ [System.Security.SecurityCritical] // auto-generated
+ [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
+ [SuppressUnmanagedCodeSecurity]
+ static private extern void DefineDynamicModule(RuntimeAssembly containingAssembly,
+ bool emitSymbolInfo,
+ String name,
+ String filename,
+ StackCrawlMarkHandle stackMark,
+ ref IntPtr pInternalSymWriter,
+ ObjectHandleOnStack retModule,
+ bool fIsTransient,
+ out int tkFile);
+
+ [System.Security.SecurityCritical] // auto-generated
+ private static Module DefineDynamicModule(RuntimeAssembly containingAssembly,
+ bool emitSymbolInfo,
+ String name,
+ String filename,
+ ref StackCrawlMark stackMark,
+ ref IntPtr pInternalSymWriter,
+ bool fIsTransient,
+ out int tkFile)
+ {
+ RuntimeModule retModule = null;
+
+ DefineDynamicModule(containingAssembly.GetNativeHandle(),
+ emitSymbolInfo,
+ name,
+ filename,
+ JitHelpers.GetStackCrawlMarkHandle(ref stackMark),
+ ref pInternalSymWriter,
+ JitHelpers.GetObjectHandleOnStack(ref retModule),
+ fIsTransient,
+ out tkFile);
+
+ return retModule;
+ }
+
+ // The following functions are native helpers for creating on-disk manifest
+ [System.Security.SecurityCritical] // auto-generated
+ [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
+ [SuppressUnmanagedCodeSecurity]
+ static private extern void PrepareForSavingManifestToDisk(RuntimeAssembly assembly, RuntimeModule assemblyModule); // module to contain assembly information if assembly is embedded
+
+ [System.Security.SecurityCritical] // auto-generated
+ [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
+ [SuppressUnmanagedCodeSecurity]
+ static private extern void SaveManifestToDisk(RuntimeAssembly assembly,
+ String strFileName,
+ int entryPoint,
+ int fileKind,
+ int portableExecutableKind,
+ int ImageFileMachine);
+
+ [System.Security.SecurityCritical] // auto-generated
+ [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
+ [SuppressUnmanagedCodeSecurity]
+ static private extern int AddFile(RuntimeAssembly assembly, String strFileName);
+
+ [System.Security.SecurityCritical] // auto-generated
+ [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
+ [SuppressUnmanagedCodeSecurity]
+ static private extern void SetFileHashValue(RuntimeAssembly assembly,
+ int tkFile,
+ String strFullFileName);
+
+ [System.Security.SecurityCritical] // auto-generated
+ [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
+ [SuppressUnmanagedCodeSecurity]
+ static private extern int AddExportedTypeInMemory(RuntimeAssembly assembly,
+ String strComTypeName,
+ int tkAssemblyRef,
+ int tkTypeDef,
+ TypeAttributes flags);
+
+ [System.Security.SecurityCritical] // auto-generated
+ [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
+ [SuppressUnmanagedCodeSecurity]
+ static private extern int AddExportedTypeOnDisk(RuntimeAssembly assembly,
+ String strComTypeName,
+ int tkAssemblyRef,
+ int tkTypeDef,
+ TypeAttributes flags);
+
+ // Add an entry to assembly's manifestResource table for a stand alone resource.
+ [System.Security.SecurityCritical] // auto-generated
+ [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
+ [SuppressUnmanagedCodeSecurity]
+ static private extern void AddStandAloneResource(RuntimeAssembly assembly,
+ String strName,
+ String strFileName,
+ String strFullFileName,
+ int attribute);
+
+ [System.Security.SecurityCritical] // auto-generated
+ [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
+ [SuppressUnmanagedCodeSecurity]
+#pragma warning disable 618
+ static private extern void AddDeclarativeSecurity(RuntimeAssembly assembly, SecurityAction action, byte[] blob, int length);
+#pragma warning restore 618
+
+ // Functions for defining unmanaged resources.
+ [System.Security.SecurityCritical] // auto-generated
+ [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
+ [SuppressUnmanagedCodeSecurity]
+ static private extern void CreateVersionInfoResource(String filename, String title, String iconFilename, String description,
+ String copyright, String trademark, String company, String product,
+ String productVersion, String fileVersion, int lcid, bool isDll,
+ StringHandleOnStack retFileName);
+ }
+}