IKVM11  11
Java SE 11 Virtual Machine for .NET
Loading...
Searching...
No Matches
ModuleResourceSectionBuilder.cs
Go to the documentation of this file.
1using System;
2using System.Collections.Generic;
3using System.IO;
4using System.Reflection.Metadata;
5using System.Reflection.PortableExecutable;
6
8
10{
11
15 class ModuleResourceSectionBuilder : ResourceSectionBuilder
16 {
17
18 const int RT_ICON = 3;
19 const int RT_GROUP_ICON = 14;
20 const int RT_VERSION = 16;
21 const int RT_MANIFEST = 24;
22
23 readonly ResourceDirectoryEntry root;
24
29 {
30 root = new ResourceDirectoryEntry(new OrdinalOrName("root"));
31 }
32
38 {
39 if (other is null)
40 throw new ArgumentNullException(nameof(other));
41
42 root = new ResourceDirectoryEntry(other.root);
43 }
44
48 public int Count => root.Count;
49
54 internal void AddVersionInfo(ByteBuffer versionInfo)
55 {
56 root[new OrdinalOrName(RT_VERSION)][new OrdinalOrName(1)][new OrdinalOrName(0)].data = versionInfo;
57 }
58
64 internal void AddIcon(byte[] iconFile)
65 {
66 var br = new BinaryReader(new MemoryStream(iconFile));
67 var idReserved = br.ReadUInt16();
68 var idType = br.ReadUInt16();
69 var idCount = br.ReadUInt16();
70 if (idReserved != 0 || idType != 1)
71 throw new ArgumentException("The supplied byte array is not a valid .ico file.");
72
73 var group = new ByteBuffer(6 + 14 * idCount);
74 group.Write(idReserved);
75 group.Write(idType);
76 group.Write(idCount);
77 for (int i = 0; i < idCount; i++)
78 {
79 var bWidth = br.ReadByte();
80 var bHeight = br.ReadByte();
81 var bColorCount = br.ReadByte();
82 var bReserved = br.ReadByte();
83 var wPlanes = br.ReadUInt16();
84 var wBitCount = br.ReadUInt16();
85 var dwBytesInRes = br.ReadUInt32();
86 var dwImageOffset = br.ReadUInt32();
87
88 // we start the icon IDs at 2
89 var id = (ushort)(2 + i);
90
91 group.Write(bWidth);
92 group.Write(bHeight);
93 group.Write(bColorCount);
94 group.Write(bReserved);
95 group.Write(wPlanes);
96 group.Write(wBitCount);
97 group.Write(dwBytesInRes);
98 group.Write(id);
99
100 var icon = new byte[dwBytesInRes];
101 Buffer.BlockCopy(iconFile, (int)dwImageOffset, icon, 0, icon.Length);
102 root[new OrdinalOrName(RT_ICON)][new OrdinalOrName(id)][new OrdinalOrName(0)].data = ByteBuffer.Wrap(icon);
103 }
104
105 root[new OrdinalOrName(RT_GROUP_ICON)][new OrdinalOrName(32512)][new OrdinalOrName(0)].data = group;
106 }
107
113 internal void AddManifest(byte[] manifest, ushort resourceID)
114 {
115 root[new OrdinalOrName(RT_MANIFEST)][new OrdinalOrName(resourceID)][new OrdinalOrName(0)].data = ByteBuffer.Wrap(manifest);
116 }
117
122 internal void ImportWin32ResourceFile(byte[] buf)
123 {
124 var br = new ByteReader(buf, 0, buf.Length);
125 while (br.Length >= 32)
126 {
127 br.Align(4);
128 var hdr = new RESOURCEHEADER(br);
129 if (hdr.DataSize != 0)
130 root[hdr.TYPE][hdr.NAME][new OrdinalOrName(hdr.LanguageId)].data = ByteBuffer.Wrap(br.ReadBytes(hdr.DataSize));
131 }
132 }
133
135 protected override void Serialize(BlobBuilder builder, SectionLocation location)
136 {
137 var bb = new ByteBuffer(1024);
138 var linkOffsets = new List<int>();
139 root.Write(bb, linkOffsets);
140
141 foreach (int offset in linkOffsets)
142 {
143 bb.Position = offset;
144 bb.Write(bb.GetInt32AtCurrentPosition() + (int)location.RelativeVirtualAddress);
145 }
146
147 builder.WriteBytes(bb.ToArray());
148 }
149
150 }
151
152}
Implements a ResourceSectionBuilder for writing IKVM reflection resource section data.
ModuleResourceSectionBuilder(ModuleResourceSectionBuilder other)
Initializes a new instance, importing the resources from the specified builder.
int Count
Gets the number of entries in the root of the builder.
override void Serialize(BlobBuilder builder, SectionLocation location)
readonly record struct OrdinalOrName(ushort Ordinal, string Name)