/// <summary> /// Writes a <see cref="VersionResource"/> object to the current <see cref="Stream"/>. /// </summary> /// <param name="resource"> /// The <see cref="VersionResource"/> to write. /// </param> public void Write(VersionResource resource) { if (resource == null) { throw new ArgumentNullException(nameof(resource)); } if (Stream.Length < resource.Size) { Stream.SetLength(resource.Size); } using (var stream = new SubStream(Stream, 0, Stream.Length, leaveParentOpen: true)) using (var writer = new BinaryWriter(stream, Encoding.Unicode)) { // Write the version resource header WriteHeader( writer, resource.Size, resource.FixedFileInfo == null ? 0 : Marshal.SizeOf(typeof(VS_FIXEDFILEINFO)), VersionDataType.Binary, "VS_VERSION_INFO"); if (resource.FixedFileInfo != null) { writer.WriteStruct(resource.FixedFileInfo.Value); } writer.Align(); if (resource.VarFileInfo != null) { WriteHeader(writer, resource.VarFileInfoSize, 0, VersionDataType.Text, "VarFileInfo"); WriteVarFileInfo(writer, resource); } if (resource.StringFileInfo != null) { WriteHeader(writer, resource.StringFileInfoSize, 0, VersionDataType.Text, "StringFileInfo"); WriteStringFileInfo(writer, resource); } } }
private void WriteHeader(BinaryWriter writer, long length, long valueLength, VersionDataType binary, string key) { var header = new VersionHeader { Length = (ushort)length, ValueLength = (ushort)valueLength, Type = binary }; writer.WriteStruct(header); writer.WriteUnicodeString(key); writer.Align(); }
private void WriteStringFileInfo(BinaryWriter writer, VersionResource resource) { foreach (var value in resource.StringFileInfo) { var languageIdentifier = value.Language; var codePage = (ushort)value.Encoding.CodePage; var key = (uint)languageIdentifier << 4 | codePage; WriteHeader(writer, value.Size, 0, VersionDataType.Text, key.ToString("x8")); foreach (var pair in value.Values) { long valueLength = Encoding.Unicode.GetByteCount(pair.Value + '\0'); long keyLength = Encoding.Unicode.GetByteCount(pair.Key + '\0'); long length = Marshal.SizeOf(typeof(VersionHeader)); length += keyLength; length = Helpers.Align(length); length += valueLength; length = Helpers.Align(length); WriteHeader(writer, length, valueLength / sizeof(short), VersionDataType.Text, pair.Key); writer.WriteUnicodeString(pair.Value); writer.Align(); } } }
/// <inheritdoc /> public override void Assemble(BinaryWriter writer) { // CONTRACT: ObjectFile // TODO: Emit .bss after the last progbits section. // Create a new context. Context context = this.ObjectFile.Architecture.CreateContext(this.ObjectFile); // Construct each section. context.Reset(); context.Address = 0; // Addresses relative to file. foreach (Section section in this.ObjectFile.Sections) { context.Section = section; string sectionName = String.Format("section.{0}.start", section.Identifier); var symbol = new Symbol(SymbolType.Private, sectionName); symbol.Define(context, context.Address); section.Construct(context); } // Emit each section and write it directly to the writer. context.Reset(); context.Address = 0; // Addresses relative to file. foreach (Section section in this.ObjectFile.Sections) { MathExt.CalculatePadding(writer.BaseStream.Position, section.Alignment); writer.Align(section.Alignment); section.Emit(writer, context); } // Test for illegal symbols. CheckSymbolSupport(context); writer.Flush(); }