Represents parts of a Stream, from a start byte offset for a given length.
Inheritance: Stream
Example #1
0
        /// <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);
                }
            }
        }
Example #2
0
        /// <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;
            }
        }