Represents an individual version resource.
예제 #1
0
        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();
                }
            }
        }
예제 #2
0
        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);
            }
        }
예제 #3
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);
                }
            }
        }
예제 #4
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);
                    }
                }
        }
예제 #5
0
        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);
            }
        }
예제 #6
0
        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();
                }
            }
        }
예제 #7
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()
        {
            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);
                }
        }
예제 #8
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;
            }
        }