Beispiel #1
0
        private AssemblyName GetNameImpl(ref AssemblyTable.Record rec)
        {
            AssemblyName name = new AssemblyName();

            name.Name    = manifestModule.GetString(rec.Name);
            name.Version = new Version(rec.MajorVersion, rec.MinorVersion, rec.BuildNumber, rec.RevisionNumber);
            if (rec.PublicKey != 0)
            {
                name.SetPublicKey(manifestModule.GetBlobCopy(rec.PublicKey));
            }
            else
            {
                name.SetPublicKey(Empty <byte> .Array);
            }
            if (rec.Culture != 0)
            {
                name.Culture = manifestModule.GetString(rec.Culture);
            }
            else
            {
                name.Culture = "";
            }
            name.HashAlgorithm = (AssemblyHashAlgorithm)rec.HashAlgId;
            name.CodeBase      = this.CodeBase;
            name.RawFlags      = (AssemblyNameFlags)rec.Flags;
            return(name);
        }
Beispiel #2
0
        private AssemblyName GetNameImpl(ref AssemblyTable.Record rec)
        {
            AssemblyName name = new AssemblyName();

            name.Name    = manifestModule.GetString(rec.Name);
            name.Version = new Version(rec.MajorVersion, rec.MinorVersion, rec.BuildNumber, rec.RevisionNumber);
            if (rec.PublicKey != 0)
            {
                name.SetPublicKey(manifestModule.GetBlobCopy(rec.PublicKey));
            }
            else
            {
                name.SetPublicKey(Empty <byte> .Array);
            }
            if (rec.Culture != 0)
            {
                name.CultureInfo = new System.Globalization.CultureInfo(manifestModule.GetString(rec.Culture));
            }
            else
            {
                name.CultureInfo = System.Globalization.CultureInfo.InvariantCulture;
            }
            switch (rec.HashAlgId)
            {
            case 0:
                name.HashAlgorithm = AssemblyHashAlgorithm.None;
                break;

            case 0x8003:
                name.HashAlgorithm = AssemblyHashAlgorithm.MD5;
                break;

            case 0x8004:
                name.HashAlgorithm = AssemblyHashAlgorithm.SHA1;
                break;

            default:
                throw new BadImageFormatException();
            }
            name.CodeBase = this.CodeBase;
            name.Flags    = (AssemblyNameFlags)rec.Flags;
            return(name);
        }
Beispiel #3
0
		private void SaveImpl(string assemblyFileName, Stream streamOrNull, PortableExecutableKinds portableExecutableKind, ImageFileMachine imageFileMachine)
		{
			ModuleBuilder manifestModule = null;

			foreach (ModuleBuilder moduleBuilder in modules)
			{
				moduleBuilder.SetIsSaved();
				moduleBuilder.PopulatePropertyAndEventTables();

				if (manifestModule == null
					&& string.Compare(moduleBuilder.fileName, assemblyFileName, StringComparison.OrdinalIgnoreCase) == 0)
				{
					manifestModule = moduleBuilder;
				}
			}

			if (manifestModule == null)
			{
				manifestModule = DefineDynamicModule("RefEmit_OnDiskManifestModule", assemblyFileName, false);
			}

			AssemblyTable.Record assemblyRecord = new AssemblyTable.Record();
			assemblyRecord.HashAlgId = (int)hashAlgorithm;
			assemblyRecord.Name = manifestModule.Strings.Add(name);
			assemblyRecord.MajorVersion = majorVersion;
			assemblyRecord.MinorVersion = minorVersion;
			assemblyRecord.BuildNumber = buildVersion;
			assemblyRecord.RevisionNumber = revisionVersion;
			if (publicKey != null)
			{
				assemblyRecord.PublicKey = manifestModule.Blobs.Add(ByteBuffer.Wrap(publicKey));
				assemblyRecord.Flags = (int)(flags | AssemblyNameFlags.PublicKey);
			}
			else
			{
				assemblyRecord.Flags = (int)(flags & ~AssemblyNameFlags.PublicKey);
			}
			if (culture != null)
			{
				assemblyRecord.Culture = manifestModule.Strings.Add(culture);
			}
			manifestModule.AssemblyTable.AddRecord(assemblyRecord);

			ResourceSection unmanagedResources = versionInfo != null || win32icon != null || win32manifest != null || win32resources != null
				? new ResourceSection()
				: null;

			if (versionInfo != null)
			{
				versionInfo.SetName(GetName());
				versionInfo.SetFileName(assemblyFileName);
				foreach (CustomAttributeBuilder cab in customAttributes)
				{
					// .NET doesn't support copying blob custom attributes into the version info
					if (!cab.HasBlob || universe.DecodeVersionInfoAttributeBlobs)
					{
						versionInfo.SetAttribute(this, cab);
					}
				}
				ByteBuffer versionInfoData = new ByteBuffer(512);
				versionInfo.Write(versionInfoData);
				unmanagedResources.AddVersionInfo(versionInfoData);
			}

			if (win32icon != null)
			{
				unmanagedResources.AddIcon(win32icon);
			}

			if (win32manifest != null)
			{
				unmanagedResources.AddManifest(win32manifest, fileKind == PEFileKinds.Dll ? (ushort)2 : (ushort)1);
			}

			if (win32resources != null)
			{
				unmanagedResources.ExtractResources(win32resources);
			}

			foreach (CustomAttributeBuilder cab in customAttributes)
			{
				// we intentionally don't filter out the version info (pseudo) custom attributes (to be compatible with .NET)
				manifestModule.SetCustomAttribute(0x20000001, cab);
			}

			manifestModule.AddDeclarativeSecurity(0x20000001, declarativeSecurity);

			foreach (TypeForwarder fwd in typeForwarders)
			{
				manifestModule.AddTypeForwarder(fwd.Type, fwd.IncludeNested);
			}

			foreach (ResourceFile resfile in resourceFiles)
			{
				if (resfile.Writer != null)
				{
					resfile.Writer.Generate();
					resfile.Writer.Close();
				}
				int fileToken = AddFile(manifestModule, resfile.FileName, 1 /*ContainsNoMetaData*/);
				ManifestResourceTable.Record rec = new ManifestResourceTable.Record();
				rec.Offset = 0;
				rec.Flags = (int)resfile.Attributes;
				rec.Name = manifestModule.Strings.Add(resfile.Name);
				rec.Implementation = fileToken;
				manifestModule.ManifestResource.AddRecord(rec);
			}

			int entryPointToken = 0;

			foreach (ModuleBuilder moduleBuilder in modules)
			{
				moduleBuilder.FillAssemblyRefTable();
				moduleBuilder.EmitResources();
				if (moduleBuilder != manifestModule)
				{
					int fileToken;
					if (entryPoint != null && entryPoint.Module == moduleBuilder)
					{
						ModuleWriter.WriteModule(null, null, moduleBuilder, fileKind, portableExecutableKind, imageFileMachine, moduleBuilder.unmanagedResources, entryPoint.MetadataToken);
						entryPointToken = fileToken = AddFile(manifestModule, moduleBuilder.fileName, 0 /*ContainsMetaData*/);
					}
					else
					{
						ModuleWriter.WriteModule(null, null, moduleBuilder, fileKind, portableExecutableKind, imageFileMachine, moduleBuilder.unmanagedResources, 0);
						fileToken = AddFile(manifestModule, moduleBuilder.fileName, 0 /*ContainsMetaData*/);
					}
					moduleBuilder.ExportTypes(fileToken, manifestModule);
				}
			}

			foreach (Module module in addedModules)
			{
				int fileToken = AddFile(manifestModule, module.FullyQualifiedName, 0 /*ContainsMetaData*/);
				module.ExportTypes(fileToken, manifestModule);
			}

			if (entryPointToken == 0 && entryPoint != null)
			{
				entryPointToken = entryPoint.MetadataToken;
			}

			// finally, write the manifest module
			ModuleWriter.WriteModule(keyPair, publicKey, manifestModule, fileKind, portableExecutableKind, imageFileMachine, unmanagedResources ?? manifestModule.unmanagedResources, entryPointToken, streamOrNull);
		}
Beispiel #4
0
        private AssemblyName GetNameImpl(ref AssemblyTable.Record rec)
        {
            AssemblyName name = new AssemblyName();

            name.Name    = manifestModule.GetString(rec.Name);
            name.Version = new Version(rec.MajorVersion, rec.MinorVersion, rec.BuildNumber, rec.RevisionNumber);
            if (rec.PublicKey != 0)
            {
                name.SetPublicKey(manifestModule.GetBlobCopy(rec.PublicKey));
            }
            else
            {
                name.SetPublicKey(Empty <byte> .Array);
            }
            if (rec.Culture != 0)
            {
                name.Culture = manifestModule.GetString(rec.Culture);
            }
            else
            {
                name.Culture = "";
            }
            name.HashAlgorithm = (AssemblyHashAlgorithm)rec.HashAlgId;
            name.CodeBase      = this.CodeBase;
            PortableExecutableKinds peKind;
            ImageFileMachine        machine;

            manifestModule.GetPEKind(out peKind, out machine);
            switch (machine)
            {
            case ImageFileMachine.I386:
                // FXBUG we copy the .NET bug that Preferred32Bit implies x86
                if ((peKind & (PortableExecutableKinds.Required32Bit | PortableExecutableKinds.Preferred32Bit)) != 0)
                {
                    name.ProcessorArchitecture = ProcessorArchitecture.X86;
                }
                else if ((rec.Flags & 0x70) == 0x70)
                {
                    // it's a reference assembly
                    name.ProcessorArchitecture = ProcessorArchitecture.None;
                }
                else
                {
                    name.ProcessorArchitecture = ProcessorArchitecture.MSIL;
                }
                break;

            case ImageFileMachine.IA64:
                name.ProcessorArchitecture = ProcessorArchitecture.IA64;
                break;

            case ImageFileMachine.AMD64:
                name.ProcessorArchitecture = ProcessorArchitecture.Amd64;
                break;

            case ImageFileMachine.ARM:
                name.ProcessorArchitecture = ProcessorArchitecture.Arm;
                break;
            }
            name.RawFlags = (AssemblyNameFlags)rec.Flags;
            return(name);
        }
Beispiel #5
0
        private void SaveImpl(string assemblyFileName, Stream streamOrNull, PortableExecutableKinds portableExecutableKind, ImageFileMachine imageFileMachine)
        {
            ModuleBuilder manifestModule = null;

            foreach (ModuleBuilder moduleBuilder in modules)
            {
                moduleBuilder.SetIsSaved();
                moduleBuilder.PopulatePropertyAndEventTables();

                if (manifestModule == null &&
                    string.Compare(moduleBuilder.fileName, assemblyFileName, StringComparison.OrdinalIgnoreCase) == 0)
                {
                    manifestModule = moduleBuilder;
                }
            }

            if (manifestModule == null)
            {
                manifestModule = DefineDynamicModule("RefEmit_OnDiskManifestModule", assemblyFileName, false);
            }

            AssemblyTable.Record assemblyRecord = new AssemblyTable.Record();
            assemblyRecord.HashAlgId      = (int)hashAlgorithm;
            assemblyRecord.Name           = manifestModule.Strings.Add(name);
            assemblyRecord.MajorVersion   = majorVersion;
            assemblyRecord.MinorVersion   = minorVersion;
            assemblyRecord.BuildNumber    = buildVersion;
            assemblyRecord.RevisionNumber = revisionVersion;
            if (publicKey != null)
            {
                assemblyRecord.PublicKey = manifestModule.Blobs.Add(ByteBuffer.Wrap(publicKey));
                assemblyRecord.Flags     = (int)(flags | AssemblyNameFlags.PublicKey);
            }
            else
            {
                assemblyRecord.Flags = (int)(flags & ~AssemblyNameFlags.PublicKey);
            }
            if (culture != null)
            {
                assemblyRecord.Culture = manifestModule.Strings.Add(culture);
            }
            manifestModule.AssemblyTable.AddRecord(assemblyRecord);

            ResourceSection unmanagedResources = versionInfo != null || win32icon != null || win32manifest != null || win32resources != null
                                ? new ResourceSection()
                                : null;

            if (versionInfo != null)
            {
                versionInfo.SetName(GetName());
                versionInfo.SetFileName(assemblyFileName);
                foreach (CustomAttributeBuilder cab in customAttributes)
                {
                    // .NET doesn't support copying blob custom attributes into the version info
                    if (!cab.HasBlob || universe.DecodeVersionInfoAttributeBlobs)
                    {
                        versionInfo.SetAttribute(this, cab);
                    }
                }
                ByteBuffer versionInfoData = new ByteBuffer(512);
                versionInfo.Write(versionInfoData);
                unmanagedResources.AddVersionInfo(versionInfoData);
            }

            if (win32icon != null)
            {
                unmanagedResources.AddIcon(win32icon);
            }

            if (win32manifest != null)
            {
                unmanagedResources.AddManifest(win32manifest, fileKind == PEFileKinds.Dll ? (ushort)2 : (ushort)1);
            }

            if (win32resources != null)
            {
                unmanagedResources.ExtractResources(win32resources);
            }

            foreach (CustomAttributeBuilder cab in customAttributes)
            {
                // we intentionally don't filter out the version info (pseudo) custom attributes (to be compatible with .NET)
                manifestModule.SetCustomAttribute(0x20000001, cab);
            }

            manifestModule.AddDeclarativeSecurity(0x20000001, declarativeSecurity);

            foreach (TypeForwarder fwd in typeForwarders)
            {
                manifestModule.AddTypeForwarder(fwd.Type, fwd.IncludeNested);
            }

            foreach (ResourceFile resfile in resourceFiles)
            {
#if !CORECLR
                if (resfile.Writer != null)
                {
                    resfile.Writer.Generate();
                    resfile.Writer.Close();
                }
#endif
                int fileToken = AddFile(manifestModule, resfile.FileName, 1 /*ContainsNoMetaData*/);
                ManifestResourceTable.Record rec = new ManifestResourceTable.Record();
                rec.Offset         = 0;
                rec.Flags          = (int)resfile.Attributes;
                rec.Name           = manifestModule.Strings.Add(resfile.Name);
                rec.Implementation = fileToken;
                manifestModule.ManifestResource.AddRecord(rec);
            }

            int entryPointToken = 0;

            foreach (ModuleBuilder moduleBuilder in modules)
            {
                moduleBuilder.FillAssemblyRefTable();
                moduleBuilder.EmitResources();
                if (moduleBuilder != manifestModule)
                {
                    int fileToken;
                    if (entryPoint != null && entryPoint.Module == moduleBuilder)
                    {
                        ModuleWriter.WriteModule(null, null, moduleBuilder, fileKind, portableExecutableKind, imageFileMachine, moduleBuilder.unmanagedResources, entryPoint.MetadataToken);
                        entryPointToken = fileToken = AddFile(manifestModule, moduleBuilder.fileName, 0 /*ContainsMetaData*/);
                    }
                    else
                    {
                        ModuleWriter.WriteModule(null, null, moduleBuilder, fileKind, portableExecutableKind, imageFileMachine, moduleBuilder.unmanagedResources, 0);
                        fileToken = AddFile(manifestModule, moduleBuilder.fileName, 0 /*ContainsMetaData*/);
                    }
                    moduleBuilder.ExportTypes(fileToken, manifestModule);
                }
                moduleBuilder.CloseResources();
            }

            foreach (Module module in addedModules)
            {
                int fileToken = AddFile(manifestModule, module.FullyQualifiedName, 0 /*ContainsMetaData*/);
                module.ExportTypes(fileToken, manifestModule);
            }

            if (entryPointToken == 0 && entryPoint != null)
            {
                entryPointToken = entryPoint.MetadataToken;
            }

            // finally, write the manifest module
            ModuleWriter.WriteModule(keyPair, publicKey, manifestModule, fileKind, portableExecutableKind, imageFileMachine, unmanagedResources ?? manifestModule.unmanagedResources, entryPointToken, streamOrNull);
        }
Beispiel #6
0
		private void SaveImpl(string assemblyFileName, Stream streamOrNull, PortableExecutableKinds portableExecutableKind, ImageFileMachine imageFileMachine)
		{
			ModuleBuilder manifestModule = null;

			foreach (ModuleBuilder moduleBuilder in modules)
			{
				moduleBuilder.PopulatePropertyAndEventTables();

				if (manifestModule == null
					&& string.Compare(moduleBuilder.fileName, assemblyFileName, StringComparison.OrdinalIgnoreCase) == 0)
				{
					manifestModule = moduleBuilder;
				}
			}

			if (manifestModule == null)
			{
				manifestModule = DefineDynamicModule("RefEmit_OnDiskManifestModule", assemblyFileName, false);
			}

			AssemblyTable.Record assemblyRecord = new AssemblyTable.Record();
			assemblyRecord.HashAlgId = (int)hashAlgorithm;
			assemblyRecord.Name = manifestModule.Strings.Add(name);
			assemblyRecord.MajorVersion = majorVersion;
			assemblyRecord.MinorVersion = minorVersion;
			assemblyRecord.BuildNumber = buildVersion;
			assemblyRecord.RevisionNumber = revisionVersion;
			if (publicKey != null)
			{
				assemblyRecord.PublicKey = manifestModule.Blobs.Add(ByteBuffer.Wrap(publicKey));
				assemblyRecord.Flags = (int)(flags | AssemblyNameFlags.PublicKey);
			}
			else
			{
				assemblyRecord.Flags = (int)(flags & ~AssemblyNameFlags.PublicKey);
			}
			if (culture != null)
			{
				assemblyRecord.Culture = manifestModule.Strings.Add(culture);
			}
			int token = 0x20000000 + manifestModule.AssemblyTable.AddRecord(assemblyRecord);

#pragma warning disable 618
			// this values are obsolete, but we already know that so we disable the warning
			System.Security.Permissions.SecurityAction requestMinimum = System.Security.Permissions.SecurityAction.RequestMinimum;
			System.Security.Permissions.SecurityAction requestOptional = System.Security.Permissions.SecurityAction.RequestOptional;
			System.Security.Permissions.SecurityAction requestRefuse = System.Security.Permissions.SecurityAction.RequestRefuse;
#pragma warning restore 618
			if (requiredPermissions != null)
			{
				manifestModule.AddDeclarativeSecurity(token, requestMinimum, requiredPermissions);
			}
			if (optionalPermissions != null)
			{
				manifestModule.AddDeclarativeSecurity(token, requestOptional, optionalPermissions);
			}
			if (refusedPermissions != null)
			{
				manifestModule.AddDeclarativeSecurity(token, requestRefuse, refusedPermissions);
			}

			if (versionInfo != null)
			{
				versionInfo.SetName(GetName());
				versionInfo.SetFileName(assemblyFileName);
				foreach (CustomAttributeBuilder cab in customAttributes)
				{
					// .NET doesn't support copying blob custom attributes into the version info
					if (!cab.HasBlob)
					{
						versionInfo.SetAttribute(cab);
					}
				}
				ByteBuffer versionInfoData = new ByteBuffer(512);
				versionInfo.Write(versionInfoData);
				if (unmanagedResources == null)
				{
					unmanagedResources = new ResourceSection();
				}
				unmanagedResources.AddVersionInfo(versionInfoData);
			}

			foreach (CustomAttributeBuilder cab in customAttributes)
			{
				// we intentionally don't filter out the version info (pseudo) custom attributes (to be compatible with .NET)
				manifestModule.SetCustomAttribute(0x20000001, cab);
			}

			manifestModule.AddDeclarativeSecurity(0x20000001, declarativeSecurity);

			foreach (Type type in typeForwarders)
			{
				manifestModule.AddTypeForwarder(type);
			}

			foreach (ResourceFile resfile in resourceFiles)
			{
				int fileToken = AddFile(manifestModule, resfile.FileName, 1 /*ContainsNoMetaData*/);
				ManifestResourceTable.Record rec = new ManifestResourceTable.Record();
				rec.Offset = 0;
				rec.Flags = (int)resfile.Attributes;
				rec.Name = manifestModule.Strings.Add(resfile.Name);
				rec.Implementation = fileToken;
				manifestModule.ManifestResource.AddRecord(rec);
			}

			int entryPointToken = 0;

			foreach (ModuleBuilder moduleBuilder in modules)
			{
				moduleBuilder.FillAssemblyRefTable();
				if (moduleBuilder != manifestModule)
				{
					int fileToken;
					if (entryPoint != null && entryPoint.Module == moduleBuilder)
					{
						ModuleWriter.WriteModule(null, null, moduleBuilder, fileKind, portableExecutableKind, imageFileMachine, moduleBuilder.unmanagedResources, entryPoint.MetadataToken);
						entryPointToken = fileToken = AddFile(manifestModule, moduleBuilder.fileName, 0 /*ContainsMetaData*/);
					}
					else
					{
						ModuleWriter.WriteModule(null, null, moduleBuilder, fileKind, portableExecutableKind, imageFileMachine, moduleBuilder.unmanagedResources, 0);
						fileToken = AddFile(manifestModule, moduleBuilder.fileName, 0 /*ContainsMetaData*/);
					}
					moduleBuilder.ExportTypes(fileToken, manifestModule);
				}
			}

			foreach (Module module in addedModules)
			{
				int fileToken = AddFile(manifestModule, module.FullyQualifiedName, 0 /*ContainsMetaData*/);
				module.ExportTypes(fileToken, manifestModule);
			}

			if (entryPointToken == 0 && entryPoint != null)
			{
				entryPointToken = entryPoint.MetadataToken;
			}

			// finally, write the manifest module
			ModuleWriter.WriteModule(keyPair, publicKey, manifestModule, fileKind, portableExecutableKind, imageFileMachine, unmanagedResources ?? manifestModule.unmanagedResources, entryPointToken, streamOrNull);
		}
        public void Save(string assemblyFileName, PortableExecutableKinds portableExecutableKind, ImageFileMachine imageFileMachine)
        {
            ModuleBuilder manifestModule = null;

            foreach (ModuleBuilder moduleBuilder in modules)
            {
                if (string.Compare(moduleBuilder.fileName, assemblyFileName, StringComparison.OrdinalIgnoreCase) == 0)
                {
                    manifestModule = moduleBuilder;
                    break;
                }
            }

            if (manifestModule == null)
            {
                manifestModule = DefineDynamicModule("RefEmit_OnDiskManifestModule", assemblyFileName, false);
            }

            if (hashAlgorithm != AssemblyHashAlgorithm.SHA1)
            {
                throw new NotImplementedException();
            }
            AssemblyTable.Record assemblyRecord = new AssemblyTable.Record();
            assemblyRecord.HashAlgId      = (int)hashAlgorithm;
            assemblyRecord.Name           = manifestModule.Strings.Add(name);
            assemblyRecord.MajorVersion   = majorVersion;
            assemblyRecord.MinorVersion   = minorVersion;
            assemblyRecord.BuildNumber    = buildVersion;
            assemblyRecord.RevisionNumber = revisionVersion;
            if (publicKey != null)
            {
                assemblyRecord.PublicKey = manifestModule.Blobs.Add(ByteBuffer.Wrap(publicKey));
                assemblyRecord.Flags     = (int)(flags | AssemblyNameFlags.PublicKey);
            }
            else
            {
                assemblyRecord.Flags = (int)(flags & ~AssemblyNameFlags.PublicKey);
            }
            if (culture != null)
            {
                assemblyRecord.Culture = manifestModule.Strings.Add(culture);
            }
            int token = 0x20000000 + manifestModule.AssemblyTable.AddRecord(assemblyRecord);

#pragma warning disable 618
            // this values are obsolete, but we already know that so we disable the warning
            System.Security.Permissions.SecurityAction requestMinimum  = System.Security.Permissions.SecurityAction.RequestMinimum;
            System.Security.Permissions.SecurityAction requestOptional = System.Security.Permissions.SecurityAction.RequestOptional;
            System.Security.Permissions.SecurityAction requestRefuse   = System.Security.Permissions.SecurityAction.RequestRefuse;
#pragma warning restore 618
            if (requiredPermissions != null)
            {
                manifestModule.AddDeclarativeSecurity(token, requestMinimum, requiredPermissions);
            }
            if (optionalPermissions != null)
            {
                manifestModule.AddDeclarativeSecurity(token, requestOptional, optionalPermissions);
            }
            if (refusedPermissions != null)
            {
                manifestModule.AddDeclarativeSecurity(token, requestRefuse, refusedPermissions);
            }

            ByteBuffer versionInfoData = null;
            if (versionInfo != null)
            {
                versionInfo.SetName(GetName());
                versionInfo.SetFileName(assemblyFileName);
                foreach (CustomAttributeBuilder cab in customAttributes)
                {
                    // .NET doesn't support copying blob custom attributes into the version info
                    if (!cab.HasBlob)
                    {
                        versionInfo.SetAttribute(cab);
                    }
                }
                versionInfoData = new ByteBuffer(512);
                versionInfo.Write(versionInfoData);
            }

            foreach (CustomAttributeBuilder cab in customAttributes)
            {
                // we intentionally don't filter out the version info (pseudo) custom attributes (to be compatible with .NET)
                manifestModule.SetCustomAttribute(0x20000001, cab);
            }

            manifestModule.AddDeclarativeSecurity(0x20000001, declarativeSecurity);

            foreach (Type type in typeForwarders)
            {
                manifestModule.AddTypeForwarder(type);
            }

            foreach (ResourceFile resfile in resourceFiles)
            {
                int fileToken = AddFile(manifestModule, resfile.FileName, 1 /*ContainsNoMetaData*/);
                ManifestResourceTable.Record rec = new ManifestResourceTable.Record();
                rec.Offset         = 0;
                rec.Flags          = (int)resfile.Attributes;
                rec.Name           = manifestModule.Strings.Add(resfile.Name);
                rec.Implementation = fileToken;
                manifestModule.ManifestResource.AddRecord(rec);
            }

            int entryPointToken = 0;

            foreach (ModuleBuilder moduleBuilder in modules)
            {
                moduleBuilder.FillAssemblyRefTable();
                if (moduleBuilder != manifestModule)
                {
                    int fileToken;
                    if (entryPoint != null && entryPoint.Module == moduleBuilder)
                    {
                        ModuleWriter.WriteModule(null, null, moduleBuilder, fileKind, portableExecutableKind, imageFileMachine, null, moduleBuilder.unmanagedResources, entryPoint.MetadataToken);
                        entryPointToken = fileToken = AddFile(manifestModule, moduleBuilder.fileName, 0 /*ContainsMetaData*/);
                    }
                    else
                    {
                        ModuleWriter.WriteModule(null, null, moduleBuilder, fileKind, portableExecutableKind, imageFileMachine, null, moduleBuilder.unmanagedResources, 0);
                        fileToken = AddFile(manifestModule, moduleBuilder.fileName, 0 /*ContainsMetaData*/);
                    }
                    moduleBuilder.ExportTypes(fileToken, manifestModule);
                }
            }

            if (entryPointToken == 0 && entryPoint != null)
            {
                entryPointToken = entryPoint.MetadataToken;
            }

            // finally, write the manifest module
            ModuleWriter.WriteModule(keyPair, publicKey, manifestModule, fileKind, portableExecutableKind, imageFileMachine, versionInfoData, unmanagedResources ?? manifestModule.unmanagedResources, entryPointToken);
        }