/// <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(ref BinaryStreamReader reader) { ulong start = reader.Offset; // Read header. var header = VersionTableEntryHeader.FromReader(ref 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(ref reader); // Read children. while (reader.Offset - start < header.Length) { reader.Align(4); result.AddEntry(ReadNextEntry(ref reader)); } return(result); }
/// <summary> /// Reads a single metadata stream header from an input stream. /// </summary> /// <param name="reader">The input stream.</param> /// <returns>The header.</returns> public static MetadataStreamHeader FromReader(ref BinaryStreamReader reader) { uint offset = reader.ReadUInt32(); uint size = reader.ReadUInt32(); string name = reader.ReadAsciiString(); reader.Align(4); return(new MetadataStreamHeader(offset, size, name)); }
private static VersionTableEntry ReadNextEntry(ref BinaryStreamReader reader) { ulong start = reader.Offset; var header = VersionTableEntryHeader.FromReader(ref reader); reader.Align(4); return(header.Key switch { VarFileInfo.VarFileInfoKey => VarFileInfo.FromReader(start, header, ref reader), StringFileInfo.StringFileInfoKey => StringFileInfo.FromReader(start, header, ref 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); }