예제 #1
0
        public bool GetInformation(IMediaImage imagePlugin, out List <Partition> partitions, ulong sectorOffset)
        {
            partitions = new List <Partition>();

            ulong sbSector;

            // RISC OS always checks for the partition on 0. Afaik no emulator chains it.
            if (sectorOffset != 0)
            {
                return(false);
            }

            if (imagePlugin.Info.SectorSize > ADFS_SB_POS)
            {
                sbSector = 0;
            }
            else
            {
                sbSector = ADFS_SB_POS / imagePlugin.Info.SectorSize;
            }

            byte[] sector = imagePlugin.ReadSector(sbSector);

            if (sector.Length < 512)
            {
                return(false);
            }

            AcornBootBlock bootBlock = Marshal.ByteArrayToStructureLittleEndian <AcornBootBlock>(sector);

            int checksum = 0;

            for (int i = 0; i < 0x1FF; i++)
            {
                checksum = (checksum & 0xFF) + (checksum >> 8) + sector[i];
            }

            int heads     = bootBlock.discRecord.heads + ((bootBlock.discRecord.lowsector >> 6) & 1);
            int secCyl    = bootBlock.discRecord.spt * heads;
            int mapSector = bootBlock.startCylinder * secCyl;

            if ((ulong)mapSector >= imagePlugin.Info.Sectors)
            {
                return(false);
            }

            byte[] map = imagePlugin.ReadSector((ulong)mapSector);

            ulong counter = 0;

            if (checksum == bootBlock.checksum)
            {
                Partition part = new Partition
                {
                    Size =
                        (ulong)bootBlock.discRecord.disc_size_high * 0x100000000 + bootBlock.discRecord.disc_size,
                    Length =
                        ((ulong)bootBlock.discRecord.disc_size_high * 0x100000000 +
                         bootBlock.discRecord.disc_size) / imagePlugin.Info.SectorSize,
                    Type = "ADFS",
                    Name = StringHandlers.CToString(bootBlock.discRecord.disc_name,
                                                    Encoding.GetEncoding("iso-8859-1"))
                };
                if (part.Size > 0)
                {
                    partitions.Add(part);
                    counter++;
                }
            }

            switch (bootBlock.flags & TYPE_MASK)
            {
            case TYPE_LINUX:
            {
                LinuxTable table = Marshal.ByteArrayToStructureLittleEndian <LinuxTable>(map);

                foreach (LinuxEntry entry in table.entries)
                {
                    Partition part = new Partition
                    {
                        Start    = (ulong)(mapSector + entry.start),
                        Size     = entry.size,
                        Length   = (ulong)(entry.size * sector.Length),
                        Sequence = counter,
                        Scheme   = Name
                    };
                    part.Offset = part.Start * (ulong)sector.Length;
                    if (entry.magic != LINUX_MAGIC && entry.magic != SWAP_MAGIC)
                    {
                        continue;
                    }

                    partitions.Add(part);
                    counter++;
                }

                break;
            }

            case TYPE_RISCIX_MFM:
            case TYPE_RISCIX_SCSI:
            {
                RiscIxTable table = Marshal.ByteArrayToStructureLittleEndian <RiscIxTable>(map);

                if (table.magic == RISCIX_MAGIC)
                {
                    foreach (RiscIxEntry entry in table.partitions)
                    {
                        Partition part = new Partition
                        {
                            Start    = (ulong)(mapSector + entry.start),
                            Size     = entry.length,
                            Length   = (ulong)(entry.length * sector.Length),
                            Name     = StringHandlers.CToString(entry.name, Encoding.GetEncoding("iso-8859-1")),
                            Sequence = counter,
                            Scheme   = Name
                        };
                        part.Offset = part.Start * (ulong)sector.Length;
                        if (entry.length <= 0)
                        {
                            continue;
                        }

                        partitions.Add(part);
                        counter++;
                    }
                }

                break;
            }
            }

            return(partitions.Count != 0);
        }