Example #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);
            }

            IntPtr bbPtr = Marshal.AllocHGlobal(512);

            Marshal.Copy(sector, 0, bbPtr, 512);
            AcornBootBlock bootBlock = (AcornBootBlock)Marshal.PtrToStructure(bbPtr, typeof(AcornBootBlock));

            Marshal.FreeHGlobal(bbPtr);

            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:
            {
                IntPtr tablePtr = Marshal.AllocHGlobal(512);
                Marshal.Copy(map, 0, tablePtr, 512);
                LinuxTable table = (LinuxTable)Marshal.PtrToStructure(tablePtr, typeof(LinuxTable));
                Marshal.FreeHGlobal(tablePtr);

                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:
            {
                IntPtr tablePtr = Marshal.AllocHGlobal(512);
                Marshal.Copy(map, 0, tablePtr, 512);
                RiscIxTable table = (RiscIxTable)Marshal.PtrToStructure(tablePtr, typeof(RiscIxTable));
                Marshal.FreeHGlobal(tablePtr);

                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);
        }
Example #2
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;
        }