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(); } } }
private void WriteVarFileInfo(BinaryWriter writer, VersionResource resource) { WriteHeader(writer, resource.VarSize, resource.VarFileInfo.Count * 4, VersionDataType.Binary, "Translation"); foreach (var value in resource.VarFileInfo) { var codePage = (ushort)value.Value.CodePage; var languageIdentifier = value.Key; writer.Write(languageIdentifier); writer.Write(codePage); } }
/// <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); } } }
/// <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 WriteVarFileInfo(BinaryWriter writer, VersionResource resource) { WriteHeader(writer, resource.VarSize, resource.VarFileInfo.Count * 4, VersionDataType.Binary, "Translation"); foreach (var value in resource.VarFileInfo) { var codePage = (ushort)value.Value.CodePage; var languageIdentifier = value.Key; writer.Write(languageIdentifier); writer.Write(codePage); } }
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(); } } }
/// <summary> /// Reads a <see cref="VersionResource"/> object from the current <see cref="Stream"/>. /// </summary> /// <returns> /// A <see cref="VersionResource"/> object. /// </returns> public VersionResource Read() { this.Stream.Position = 0; VersionResource value = new VersionResource(); using (SubStream stream = new SubStream(this.Stream, 0, this.Stream.Length, leaveParentOpen: true)) using (BinaryReader reader = new BinaryReader(stream, Encoding.Default)) { long offset = this.Stream.Position; var versionInfo = reader.ReadVersionInfo(); long end = offset + versionInfo.Header.Length; // The root element MUST be a "VS_VERSION_INFO" element of binary type. // https://msdn.microsoft.com/en-us/library/windows/desktop/ms647001(v=vs.85).aspx // It contains at most three children - a VS_FIXEDFILEINFO object, a StringFileInfo struct // and a VarFileInfo struct. if (versionInfo.Key != "VS_VERSION_INFO") { throw new VersionResourceFormatException(); } if (versionInfo.Header.Type != VersionDataType.Binary) { throw new VersionResourceFormatException(); } // We know a VS_FIXEDFILEINFO struct is present if the ValueLength > 0 if (versionInfo.Header.ValueLength != 0) { // Read the file info value.FixedFileInfo = reader.ReadStruct <VS_FIXEDFILEINFO>(); reader.Align(); } // Read the children: At most one StringFileInfo and at most one VarFileInfo while (this.Stream.Position < end) { var childOffset = this.Stream.Position; var childInfo = reader.ReadVersionInfo(); long childEnd = childOffset + childInfo.Header.Length; switch (childInfo.Key) { case "VarFileInfo": if (childInfo.Header.Type != VersionDataType.Text) { throw new VersionResourceFormatException(); } value.VarFileInfo = this.ReadVarFileInfo(reader); break; case "StringFileInfo": if (childInfo.Header.Type != VersionDataType.Text) { throw new VersionResourceFormatException(); } value.StringFileInfo = this.ReadStringFileInfo(reader, childEnd); break; } } return(value); } }
/// <summary> /// Reads a <see cref="VersionResource"/> object from the current <see cref="Stream"/>. /// </summary> /// <returns> /// A <see cref="VersionResource"/> object. /// </returns> public VersionResource Read() { Stream.Position = 0; var value = new VersionResource(); using (var stream = new SubStream(Stream, 0, Stream.Length, leaveParentOpen: true)) using (var reader = new BinaryReader(stream, Encoding.Default)) { var offset = Stream.Position; var versionInfo = reader.ReadVersionInfo(); var end = offset + versionInfo.Header.Length; // The root element MUST be a "VS_VERSION_INFO" element of binary type. // https://msdn.microsoft.com/en-us/library/windows/desktop/ms647001(v=vs.85).aspx // It contains at most three children - a VS_FIXEDFILEINFO object, a StringFileInfo struct // and a VarFileInfo struct. if (versionInfo.Key != "VS_VERSION_INFO") { throw new VersionResourceFormatException(); } if (versionInfo.Header.Type != VersionDataType.Binary) { throw new VersionResourceFormatException(); } // We know a VS_FIXEDFILEINFO struct is present if the ValueLength > 0 if (versionInfo.Header.ValueLength != 0) { // Read the file info value.FixedFileInfo = reader.ReadStruct<VS_FIXEDFILEINFO>(); reader.Align(); } // Read the children: At most one StringFileInfo and at most one VarFileInfo while (Stream.Position < end) { var childOffset = Stream.Position; var childInfo = reader.ReadVersionInfo(); var childEnd = childOffset + childInfo.Header.Length; switch (childInfo.Key) { case "VarFileInfo": if (childInfo.Header.Type != VersionDataType.Text) { throw new VersionResourceFormatException(); } value.VarFileInfo = ReadVarFileInfo(reader); break; case "StringFileInfo": if (childInfo.Header.Type != VersionDataType.Text) { throw new VersionResourceFormatException(); } value.StringFileInfo = ReadStringFileInfo(reader, childEnd); break; } } return value; } }