void Initialize() { Recognized = false; if (BaseStream == null) { return; } byte[] buffer = new byte[Marshal.SizeOf(typeof(MZHeader))]; BaseStream.Position = 0; BaseStream.Read(buffer, 0, buffer.Length); IntPtr hdrPtr = Marshal.AllocHGlobal(buffer.Length); Marshal.Copy(buffer, 0, hdrPtr, buffer.Length); Header = (MZHeader)Marshal.PtrToStructure(hdrPtr, typeof(MZHeader)); Marshal.FreeHGlobal(hdrPtr); Recognized = Header.signature == SIGNATURE; if (!Recognized) { return; } Type = "DOS Executable (MZ)"; RequiredOperatingSystem = new OperatingSystem { Name = "DOS" }; if (ResourceStream == null) { return; } buffer = new byte[Marshal.SizeOf(typeof(GEM.GemResourceHeader))]; ResourceStream.Position = 0; ResourceStream.Read(buffer, 0, buffer.Length); GEM.GemResourceHeader gemResourceHeader = BigEndianMarshal.ByteArrayToStructureLittleEndian <GEM.GemResourceHeader>(buffer); if (gemResourceHeader.rsh_vrsn != 0 && gemResourceHeader.rsh_vrsn != 1 && gemResourceHeader.rsh_vrsn != 3 && gemResourceHeader.rsh_vrsn != 4 && gemResourceHeader.rsh_vrsn != 5) { return; } RequiredOperatingSystem = new OperatingSystem { Name = "PC-GEM" }; if (gemResourceHeader.rsh_vrsn == 3) { buffer = new byte[Marshal.SizeOf(typeof(GEM.MagiCResourceHeader))]; ResourceStream.Position = 0; ResourceStream.Read(buffer, 0, buffer.Length); ResourceHeader = BigEndianMarshal.ByteArrayToStructureLittleEndian <GEM.MagiCResourceHeader>(buffer); RequiredOperatingSystem = new OperatingSystem { Name = "MagiC" }; } else { ResourceHeader = GEM.GemToMagiC(gemResourceHeader); } if ((ResourceHeader.rsh_vrsn & 4) == 4) { buffer = new byte[Marshal.SizeOf(typeof(GEM.GemResourceExtension))]; ResourceStream.Position = ResourceHeader.rsh_rssize; ResourceStream.Read(buffer, 0, buffer.Length); ResourceExtension = BigEndianMarshal.ByteArrayToStructureLittleEndian <GEM.GemResourceExtension>(buffer); GemColorIcons = GEM.GetColorIcons(ResourceStream, ResourceExtension.color_ic, false, Encoding.GemEncoding); } List <string> strings = new List <string>(); if (ResourceHeader.rsh_ntree > 0) { ResourceStream.Position = ResourceHeader.rsh_trindex; int[] treeOffsets = new int[ResourceHeader.rsh_ntree]; byte[] tmp = new byte[4]; for (int i = 0; i < ResourceHeader.rsh_ntree; i++) { ResourceStream.Read(tmp, 0, 4); treeOffsets[i] = BitConverter.ToInt32(tmp, 0); } ResourceObjectRoots = new GEM.TreeObjectNode[ResourceHeader.rsh_ntree]; for (int i = 0; i < ResourceHeader.rsh_ntree; i++) { if (treeOffsets[i] <= 0 || treeOffsets[i] >= ResourceStream.Length) { continue; } ResourceStream.Position = treeOffsets[i]; List <GEM.ObjectNode> nodes = new List <GEM.ObjectNode>(); while (true) { buffer = new byte[Marshal.SizeOf(typeof(GEM.ObjectNode))]; ResourceStream.Read(buffer, 0, buffer.Length); GEM.ObjectNode node = BigEndianMarshal.ByteArrayToStructureLittleEndian <GEM.ObjectNode>(buffer); nodes.Add(node); if (((GEM.ObjectFlags)node.ob_flags).HasFlag(GEM.ObjectFlags.Lastob)) { break; } } List <short> knownNodes = new List <short>(); ResourceObjectRoots[i] = GEM.ProcessResourceObject(nodes, ref knownNodes, 0, ResourceStream, strings, false, Encoding.GemEncoding); } } else if (ResourceHeader.rsh_nobs > 0) { GEM.ObjectNode[] nodes = new GEM.ObjectNode[ResourceHeader.rsh_nobs]; ResourceStream.Position = ResourceHeader.rsh_object; for (short i = 0; i < ResourceHeader.rsh_nobs; i++) { buffer = new byte[Marshal.SizeOf(typeof(GEM.ObjectNode))]; ResourceStream.Read(buffer, 0, buffer.Length); nodes[i] = BigEndianMarshal.ByteArrayToStructureLittleEndian <GEM.ObjectNode>(buffer); } List <short> knownNodes = new List <short>(); ResourceObjectRoots = new GEM.TreeObjectNode[1]; // TODO: Correct encoding? ResourceObjectRoots[0] = GEM.ProcessResourceObject(nodes, ref knownNodes, 0, ResourceStream, strings, false, Encoding.GemEncoding); } if (strings.Count > 0) { strings.Sort(); Strings = strings.Distinct(); } }
void Initialize() { Recognized = false; if (BaseStream == null) { return; } byte[] buffer = new byte[Marshal.SizeOf(typeof(AtariHeader))]; BaseStream.Position = 0; BaseStream.Read(buffer, 0, buffer.Length); Header = BigEndianMarshal.ByteArrayToStructureBigEndian <AtariHeader>(buffer); Recognized = Header.signature == SIGNATURE; List <string> strings = new List <string>(); if (!Recognized) { return; } Type = "Atari ST executable"; if (Header.symb_len != 0) { BaseStream.Position = 0x1C + Header.text_len + Header.data_len; buffer = new byte[Marshal.SizeOf(typeof(SymbolEntry))]; symbols = new SymbolEntry[Header.symb_len / Marshal.SizeOf(typeof(SymbolEntry))]; for (int i = 0; i < symbols.Length; i++) { BaseStream.Read(buffer, 0, buffer.Length); symbols[i] = new SymbolEntry(); symbols[i] = BigEndianMarshal.ByteArrayToStructureBigEndian <SymbolEntry>(buffer); symbols[i].type = (SymbolType)Swapping.Swap((ushort)symbols[i].type); strings.Add(StringHandlers.CToString(symbols[i].name, Encoding.AtariSTEncoding)); } } Segments = new [] { new Segment { Name = ".text", Flags = $"{(PrgFlags)(Header.flags & 0xFFCF)} {(PrgSharing)(Header.flags & PF_SHARE_MASK)}", Offset = 0x1C, Size = Header.text_len }, new Segment { Name = ".data", Flags = "", Offset = 0x1C + Header.text_len, Size = Header.data_len }, new Segment { Name = ".bss", Flags = "", Offset = 0, Size = Header.bss_len } }; RequiredOperatingSystem = new OperatingSystem { Name = Header.mint == MINT_SIGNATURE ? "MiNT" : "Atari TOS" }; if (ResourceStream == null) { return; } buffer = new byte[Marshal.SizeOf(typeof(GEM.GemResourceHeader))]; ResourceStream.Position = 0; ResourceStream.Read(buffer, 0, buffer.Length); GEM.GemResourceHeader gemResourceHeader = BigEndianMarshal.ByteArrayToStructureBigEndian <GEM.GemResourceHeader>(buffer); if (gemResourceHeader.rsh_vrsn != 0 && gemResourceHeader.rsh_vrsn != 1 && gemResourceHeader.rsh_vrsn != 3 && gemResourceHeader.rsh_vrsn != 4 && gemResourceHeader.rsh_vrsn != 5) { return; } if (gemResourceHeader.rsh_vrsn == 3) { buffer = new byte[Marshal.SizeOf(typeof(GEM.MagiCResourceHeader))]; ResourceStream.Position = 0; ResourceStream.Read(buffer, 0, buffer.Length); ResourceHeader = BigEndianMarshal.ByteArrayToStructureBigEndian <GEM.MagiCResourceHeader>(buffer); RequiredOperatingSystem = new OperatingSystem { Name = "MagiC" }; } else { ResourceHeader = GEM.GemToMagiC(gemResourceHeader); } if ((ResourceHeader.rsh_vrsn & 4) == 4) { buffer = new byte[Marshal.SizeOf(typeof(GEM.GemResourceExtension))]; ResourceStream.Position = ResourceHeader.rsh_rssize; ResourceStream.Read(buffer, 0, buffer.Length); ResourceExtension = BigEndianMarshal.ByteArrayToStructureBigEndian <GEM.GemResourceExtension>(buffer); GemColorIcons = GEM.GetColorIcons(ResourceStream, ResourceExtension.color_ic, true, Encoding.AtariSTEncoding); } if (ResourceHeader.rsh_ntree > 0) { ResourceStream.Position = ResourceHeader.rsh_trindex; int[] treeOffsets = new int[ResourceHeader.rsh_ntree]; byte[] tmp = new byte[4]; for (int i = 0; i < ResourceHeader.rsh_ntree; i++) { ResourceStream.Read(tmp, 0, 4); treeOffsets[i] = BitConverter.ToInt32(tmp.Reverse().ToArray(), 0); } ResourceObjectRoots = new GEM.TreeObjectNode[ResourceHeader.rsh_ntree]; for (int i = 0; i < ResourceHeader.rsh_ntree; i++) { if (treeOffsets[i] <= 0 || treeOffsets[i] >= ResourceStream.Length) { continue; } ResourceStream.Position = treeOffsets[i]; List <GEM.ObjectNode> nodes = new List <GEM.ObjectNode>(); while (true) { buffer = new byte[Marshal.SizeOf(typeof(GEM.ObjectNode))]; ResourceStream.Read(buffer, 0, buffer.Length); GEM.ObjectNode node = BigEndianMarshal.ByteArrayToStructureBigEndian <GEM.ObjectNode>(buffer); nodes.Add(node); if (((GEM.ObjectFlags)node.ob_flags).HasFlag(GEM.ObjectFlags.Lastob)) { break; } } List <short> knownNodes = new List <short>(); ResourceObjectRoots[i] = GEM.ProcessResourceObject(nodes, ref knownNodes, 0, ResourceStream, strings, true, Encoding.AtariSTEncoding); } } else if (ResourceHeader.rsh_nobs > 0) { GEM.ObjectNode[] nodes = new GEM.ObjectNode[ResourceHeader.rsh_nobs]; ResourceStream.Position = ResourceHeader.rsh_object; for (short i = 0; i < ResourceHeader.rsh_nobs; i++) { buffer = new byte[Marshal.SizeOf(typeof(GEM.ObjectNode))]; ResourceStream.Read(buffer, 0, buffer.Length); nodes[i] = BigEndianMarshal.ByteArrayToStructureBigEndian <GEM.ObjectNode>(buffer); } List <short> knownNodes = new List <short>(); ResourceObjectRoots = new GEM.TreeObjectNode[1]; ResourceObjectRoots[0] = GEM.ProcessResourceObject(nodes, ref knownNodes, 0, ResourceStream, strings, true, Encoding.AtariSTEncoding); } if (strings.Count > 0) { strings.Sort(); Strings = strings.Distinct(); } }