/// <summary> /// Reads a version resource from an input stream. /// </summary> /// <param name="reader">The input stream.</param> /// <returns>The parsed version resource.</returns> /// <exception cref="FormatException"> /// Occurs when the input stream does not point to a valid version resource. /// </exception> public static VersionInfoResource FromReader(IBinaryStreamReader reader) { uint start = reader.FileOffset; // Read header. var header = VersionTableEntryHeader.FromReader(reader); if (header.Key != VsVersionInfoKey) { throw new FormatException($"Input stream does not point to a {VsVersionInfoKey} entry."); } var result = new VersionInfoResource(); // Read fixed version info. reader.Align(4); result.FixedVersionInfo = FixedVersionInfo.FromReader(reader); // Read children. while (reader.FileOffset - start < header.Length) { reader.Align(4); result.AddEntry(ReadNextEntry(reader)); } return(result); }
/// <inheritdoc /> public override uint GetPhysicalSize() { uint size = VersionTableEntryHeader.GetHeaderSize(Key); size = size.Align(4); size += (uint)Values.Count * sizeof(uint); return(size); }
/// <summary> /// Reads a single StringFileInfo structure from the provided input stream. /// </summary> /// <param name="startOffset">The offset of the consumed header.</param> /// <param name="header">The header.</param> /// <param name="reader">The input stream.</param> /// <returns>The read structure.</returns> /// <remarks> /// This function assumes the provided header was already consumed. /// </remarks> public static StringFileInfo FromReader(ulong startOffset, VersionTableEntryHeader header, ref BinaryStreamReader reader) { var result = new StringFileInfo(); while (reader.Offset - startOffset < header.Length) { result.Tables.Add(StringTable.FromReader(ref reader)); } return(result); }
/// <summary> /// Reads a single VarFileInfo structure from the provided input stream. /// </summary> /// <param name="startOffset">The offset of the consumed header.</param> /// <param name="header">The header.</param> /// <param name="reader">The input stream.</param> /// <returns>The read structure.</returns> /// <remarks> /// This function assumes the provided header was already consumed. /// </remarks> public static VarFileInfo FromReader(uint startOffset, VersionTableEntryHeader header, IBinaryStreamReader reader) { var result = new VarFileInfo(); while (reader.FileOffset - startOffset < header.Length) { result.Tables.Add(VarTable.FromReader(reader)); } return(result); }
/// <inheritdoc /> public override uint GetPhysicalSize() { uint size = VersionTableEntryHeader.GetHeaderSize(Key); for (int i = 0; i < Tables.Count; i++) { size = size.Align(4); size += Tables[i].GetPhysicalSize(); } return(size); }
private static VersionTableEntry ReadNextEntry(IBinaryStreamReader reader) { uint start = reader.FileOffset; var header = VersionTableEntryHeader.FromReader(reader); reader.Align(4); return(header.Key switch { VarFileInfo.VarFileInfoKey => VarFileInfo.FromReader(start, header, reader), StringFileInfo.StringFileInfoKey => StringFileInfo.FromReader(start, header, reader), _ => throw new FormatException($"Invalid or unsupported entry {header.Key}.") });
/// <summary> /// Reads a single Var table at the provided input stream. /// </summary> /// <param name="reader">The input stream.</param> /// <returns>The var table.</returns> /// <exception cref="FormatException"> /// Occurs when the input stream does not point to a valid Var table structure. /// </exception> public static VarTable FromReader(ref BinaryStreamReader reader) { var header = VersionTableEntryHeader.FromReader(ref reader); if (header.Key != TranslationKey) { throw new FormatException($"Expected a Var structure but got a {header.Key} structure."); } reader.Align(4); var result = new VarTable(); ulong start = reader.Offset; while (reader.Offset - start < header.ValueLength) { result.Values.Add(reader.ReadUInt32()); } return(result); }
private static KeyValuePair <string, string> ReadEntry(ref BinaryStreamReader reader) { ulong start = reader.Offset; // Read header. var header = VersionTableEntryHeader.FromReader(ref reader); reader.Align(4); // Read value. var data = new byte[header.ValueLength * sizeof(char)]; int count = reader.ReadBytes(data, 0, data.Length); // Exclude zero terminator. count = Math.Max(count - 2, 0); string value = Encoding.Unicode.GetString(data, 0, count); // Skip any unprocessed bytes. reader.Offset = start + header.Length; return(new KeyValuePair <string, string>(header.Key, value)); }
/// <summary> /// Reads a single StringTable structure from the provided input stream. /// </summary> /// <param name="reader">The input stream.</param> /// <returns>The read structure.</returns> public static StringTable FromReader(ref BinaryStreamReader reader) { ulong start = reader.Offset; // Read header. var header = VersionTableEntryHeader.FromReader(ref reader); if (header.Key.Length != 8 || !uint.TryParse(header.Key, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out uint rawKey)) { throw new FormatException("Invalid string table language identifier or code page."); } var result = new StringTable((ushort)(rawKey >> 16), (ushort)(rawKey & 0xFFFF)); // Read entries. while (reader.Offset - start < header.Length) { reader.Align(4); var entry = ReadEntry(ref reader); result.Add(entry.Key, entry.Value); } return(result); }