Пример #1
0
        /// <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);
        }
Пример #2
0
        /// <inheritdoc />
        public override uint GetPhysicalSize()
        {
            uint size = VersionTableEntryHeader.GetHeaderSize(Key);

            size  = size.Align(4);
            size += (uint)Values.Count * sizeof(uint);
            return(size);
        }
Пример #3
0
        /// <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);
        }
Пример #4
0
        /// <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);
        }
Пример #5
0
        /// <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);
        }
Пример #6
0
        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}.")
            });
Пример #7
0
        /// <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);
        }
Пример #8
0
        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));
        }
Пример #9
0
        /// <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);
        }