| 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. |
| 2 | |
| 3 | namespace WixToolset.Dtf.Resources |
| 4 | { |
| 5 | using System; |
| 6 | using System.IO; |
| 7 | using System.Text; |
| 8 | using System.Reflection; |
| 9 | using System.Collections; |
| 10 | using System.Globalization; |
| 11 | using System.Diagnostics.CodeAnalysis; |
| 12 | |
| 13 | internal enum GroupIconType |
| 14 | { |
| 15 | Unknown, |
| 16 | Icon, |
| 17 | Cursor, |
| 18 | } |
| 19 | |
| 20 | internal struct GroupIconDirectoryInfo |
| 21 | { |
| 22 | public byte width; |
| 23 | public byte height; |
| 24 | public byte colors; |
| 25 | public byte reserved; |
| 26 | public ushort planes; |
| 27 | public ushort bitsPerPixel; |
| 28 | public uint imageSize; |
| 29 | public uint imageOffset; // only valid when icon group is read from .ico file. |
| 30 | public ushort imageIndex; // only valid when icon group is read from PE resource. |
| 31 | } |
| 32 | |
| 33 | internal class GroupIconInfo |
| 34 | { |
| 35 | private ushort reserved; |
| 36 | private GroupIconType type; |
| 37 | private GroupIconDirectoryInfo[] images; |
| 38 | |
| 39 | public GroupIconInfo() |
| 40 | { |
| 41 | this.images = new GroupIconDirectoryInfo[0]; |
| 42 | } |
| 43 | |
| 44 | public GroupIconDirectoryInfo[] DirectoryInfo { get { return this.images; } } |
| 45 | |
| 46 | public void ReadFromFile(Stream stream) |
| 47 | { |
| 48 | BinaryReader reader = new BinaryReader(stream); |
| 49 | this.Read(reader, true); |
| 50 | } |
| 51 | |
| 52 | public void ReadFromResource(byte[] data) |
| 53 | { |
| 54 | using (BinaryReader reader = new BinaryReader(new MemoryStream(data, false))) |
| 55 | { |
| 56 | this.Read(reader, false); |
| 57 | } |
| 58 | } |
| 59 | |
| 60 | public byte[] GetResourceData() |
| 61 | { |
| 62 | byte[] data = null; |
| 63 | |
| 64 | using (MemoryStream stream = new MemoryStream()) |
| 65 | { |
| 66 | BinaryWriter writer = new BinaryWriter(stream); |
| 67 | writer.Write(this.reserved); |
| 68 | writer.Write((ushort)this.type); |
| 69 | writer.Write((ushort)this.images.Length); |
| 70 | for (int i = 0; i < this.images.Length; ++i) |
| 71 | { |
| 72 | writer.Write(this.images[i].width); |
| 73 | writer.Write(this.images[i].height); |
| 74 | writer.Write(this.images[i].colors); |
| 75 | writer.Write(this.images[i].reserved); |
| 76 | writer.Write(this.images[i].planes); |
| 77 | writer.Write(this.images[i].bitsPerPixel); |
| 78 | writer.Write(this.images[i].imageSize); |
| 79 | writer.Write(this.images[i].imageIndex); |
| 80 | } |
| 81 | |
| 82 | data = new byte[stream.Length]; |
| 83 | stream.Seek(0, SeekOrigin.Begin); |
| 84 | stream.Read(data, 0, data.Length); |
| 85 | } |
| 86 | |
| 87 | return data; |
| 88 | } |
| 89 | |
| 90 | private void Read(BinaryReader reader, bool readFromFile) |
| 91 | { |
| 92 | this.reserved = reader.ReadUInt16(); |
| 93 | this.type = (GroupIconType)reader.ReadUInt16(); |
| 94 | |
| 95 | int imageCount = reader.ReadUInt16(); |
| 96 | this.images = new GroupIconDirectoryInfo[imageCount]; |
| 97 | for (int i = 0; i < imageCount; ++i) |
| 98 | { |
| 99 | this.images[i].width = reader.ReadByte(); |
| 100 | this.images[i].height = reader.ReadByte(); |
| 101 | this.images[i].colors = reader.ReadByte(); |
| 102 | this.images[i].reserved = reader.ReadByte(); |
| 103 | this.images[i].planes = reader.ReadUInt16(); |
| 104 | this.images[i].bitsPerPixel = reader.ReadUInt16(); |
| 105 | this.images[i].imageSize = reader.ReadUInt32(); |
| 106 | if (readFromFile) |
| 107 | { |
| 108 | this.images[i].imageOffset = reader.ReadUInt32(); |
| 109 | this.images[i].imageIndex = (ushort)(i + 1); |
| 110 | } |
| 111 | else |
| 112 | { |
| 113 | this.images[i].imageIndex = reader.ReadUInt16(); |
| 114 | } |
| 115 | } |
| 116 | } |
| 117 | |
| 118 | } |
| 119 | } |