Ejemplo n.º 1
0
        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();
            }
        }
Ejemplo n.º 2
0
        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();
            }
        }