ResourceDirectoryTable CloneResourceDirectoryTable (ResourceDirectoryTable old) { ResourceDirectoryTable rdt = new ResourceDirectoryTable (); foreach (ResourceDirectoryEntry oldEntry in old.Entries) rdt.Entries.Add (CloneResourceDirectoryEntry (oldEntry)); return rdt; }
ResourceDirectoryTable CloneResourceDirectoryTable(ResourceDirectoryTable old) { ResourceDirectoryTable rdt = new ResourceDirectoryTable(); foreach (ResourceDirectoryEntry oldEntry in old.Entries) { rdt.Entries.Add(CloneResourceDirectoryEntry(oldEntry)); } return(rdt); }
static ResourceNode GetResourceNode(Stream stream, long position, long rsrcVa, long rsrcStart, uint id, string name, int level) { long oldPosition = stream.Position; ResourceNode thisNode = new ResourceNode { name = name, id = id, level = level }; if (thisNode.name == null) { thisNode.name = level == 1 ? Windows.Resources.IdToName((ushort)thisNode.id) : $"{thisNode.id}"; } stream.Position = position; byte[] buffer = new byte[Marshal.SizeOf(typeof(ResourceDirectoryTable))]; stream.Read(buffer, 0, buffer.Length); ResourceDirectoryTable rsrcTable = BigEndianMarshal.ByteArrayToStructureLittleEndian <ResourceDirectoryTable>(buffer); buffer = new byte[Marshal.SizeOf(typeof(ResourceDirectoryEntries))]; ResourceDirectoryEntries[] entries = new ResourceDirectoryEntries[rsrcTable.nameEntries + rsrcTable.idEntries]; for (int i = 0; i < rsrcTable.nameEntries; i++) { stream.Read(buffer, 0, buffer.Length); entries[i] = BigEndianMarshal.ByteArrayToStructureLittleEndian <ResourceDirectoryEntries>(buffer); } for (int i = 0; i < rsrcTable.idEntries; i++) { stream.Read(buffer, 0, buffer.Length); entries[rsrcTable.nameEntries + i] = BigEndianMarshal.ByteArrayToStructureLittleEndian <ResourceDirectoryEntries>(buffer); } thisNode.children = new ResourceNode[entries.Length]; for (int i = 0; i < rsrcTable.nameEntries; i++) { byte[] len = new byte[2]; stream.Position = rsrcStart + (entries[i].nameOrID & 0x7FFFFFFF); stream.Read(len, 0, 2); buffer = new byte[BitConverter.ToUInt16(len, 0) * 2]; stream.Read(buffer, 0, buffer.Length); string childName = Encoding.Unicode.GetString(buffer); if ((entries[i].rva & 0x80000000) == 0x80000000) { thisNode.children[i] = GetResourceNode(stream, rsrcStart + (entries[i].rva & 0x7FFFFFFF), rsrcVa, rsrcStart, 0, childName, level + 1); } else { buffer = new byte[Marshal.SizeOf(typeof(ResourceDataEntry))]; stream.Position = rsrcStart + (entries[i].rva & 0x7FFFFFFF); stream.Read(buffer, 0, buffer.Length); ResourceDataEntry dataEntry = BigEndianMarshal.ByteArrayToStructureLittleEndian <ResourceDataEntry>(buffer); thisNode.children[i] = new ResourceNode { data = new byte[dataEntry.size], id = 0, name = childName, level = level + 1 }; stream.Position = dataEntry.rva - (rsrcVa - rsrcStart); stream.Read(thisNode.children[i].data, 0, (int)dataEntry.size); } } for (int i = rsrcTable.nameEntries; i < rsrcTable.nameEntries + rsrcTable.idEntries; i++) { if ((entries[i].rva & 0x80000000) == 0x80000000) { thisNode.children[i] = GetResourceNode(stream, rsrcStart + (entries[i].rva & 0x7FFFFFFF), rsrcVa, rsrcStart, entries[i].nameOrID & 0x7FFFFFFF, null, level + 1); } else { buffer = new byte[Marshal.SizeOf(typeof(ResourceDataEntry))]; stream.Position = rsrcStart + (entries[i].rva & 0x7FFFFFFF); stream.Read(buffer, 0, buffer.Length); ResourceDataEntry dataEntry = BigEndianMarshal.ByteArrayToStructureLittleEndian <ResourceDataEntry>(buffer); thisNode.children[i] = new ResourceNode { data = new byte[dataEntry.size], id = entries[i].nameOrID & 0x7FFFFFFF, name = $"{entries[i].nameOrID & 0x7FFFFFFF}", level = level + 1 }; if (level == 2) { if (thisNode.children[i].id == 0) { thisNode.children[i].name = "Neutral"; } else { try { thisNode.children[i].name = new CultureInfo((int)thisNode.children[i].id).DisplayName; } catch { thisNode.children[i].name = $"Language ID {thisNode.children[i].id}"; } } } stream.Position = dataEntry.rva - (rsrcVa - rsrcStart); stream.Read(thisNode.children[i].data, 0, (int)dataEntry.size); } } stream.Position = oldPosition; return(thisNode); }