// /*************************************************************************** // The Disc Image Chef // ---------------------------------------------------------------------------- // // Filename : RDB.cs // Author(s) : Natalia Portillo // // Component : Partitioning scheme plugins. // // --[ Description ] ---------------------------------------------------------- // // Manages Amiga Rigid Disk Block. // // --[ License ] -------------------------------------------------------------- // // This library is free software; you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as // published by the Free Software Foundation; either version 2.1 of the // License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, see . // // ---------------------------------------------------------------------------- // Copyright © 2011-2017 Natalia Portillo // ****************************************************************************/ using System; using System.Collections.Generic; using System.Text; using DiscImageChef.Console; namespace DiscImageChef.PartPlugins { public class AmigaRigidDiskBlock : PartPlugin { /// /// RDB magic number "RDSK" /// const uint RigidDiskBlockMagic = 0x5244534B; /// /// Bad block list magic number "BADB" /// const uint BadBlockListMagic = 0x42414442; /// /// Partition entry magic number "PART" /// const uint PartitionBlockMagic = 0x50415254; /// /// Filesystem header magic number "FSHD" /// const uint FilesystemHeaderMagic = 0x46534844; /// /// LoadSeg block magic number "LSEG" /// const uint LoadSegMagic = 0x4C534547; /// /// Type ID for Amiga Original File System, "DOS\0" /// const uint TypeIDOFS = 0x444F5300; /// /// Type ID for Amiga Fast File System, "DOS\1" /// const uint TypeIDFFS = 0x444F5301; /// /// Type ID for Amiga Original File System with international characters, "DOS\2" /// const uint TypeIDOFSi = 0x444F5302; /// /// Type ID for Amiga Fast File System with international characters, "DOS\3" /// const uint TypeIDFFSi = 0x444F5303; /// /// Type ID for Amiga Original File System with directory cache, "DOS\4" /// const uint TypeIDOFSc = 0x444F5304; /// /// Type ID for Amiga Fast File System with directory cache, "DOS\5" /// const uint TypeIDFFSc = 0x444F5305; /// /// Type ID for Amiga Original File System with long filenames, "DOS\6" /// const uint TypeIDOFS2 = 0x444F5306; /// /// Type ID for Amiga Fast File System with long filenames, "DOS\7" /// const uint TypeIDFFS2 = 0x444F5307; /// /// Type ID for Amiga UNIX System V filesystem /// const uint TypeIDAMIXSysV = 0x554E4900; /// /// Type ID for Amiga UNIX boot filesystem /// const uint TypeIDAMIXBoot = 0x554E4901; /// /// Type ID for Amiga UNIX BSD filesystem /// const uint TypeIDAMIXFFS = 0x554E4902; /// /// Type ID for Amiga UNIX Reserved partition (swap) /// const uint TypeIDAMIXReserved = 0x72657376; /// /// Type ID for ProfessionalFileSystem, "PFS\1" /// const uint TypeIDPFS = 0x50465301; /// /// Type ID for ProfessionalFileSystem, "PFS\2" /// const uint TypeIDPFS2 = 0x50465302; /// /// Type ID for ProfessionalFileSystem, "muAF" /// const uint TypeIDPFSm = 0x6D754146; /// /// Type ID for ProfessionalFileSystem, "AFS\1" /// const uint TypeIDAFS = 0x41465301; /// /// Type ID for SmartFileSystem v1, "SFS\0" /// const uint TypeIDSFS = 0x53465300; /// /// Type ID for SmartFileSystem v2, "SFS\2" /// const uint TypeIDSFS2 = 0x53465302; /// /// Type ID for JXFS, "JXF\4" /// const uint TypeIDJXFS = 0x4A584604; /// /// Type ID for FAT, as set by CrossDOS, "MSD\0" /// const uint TypeIDCrossDOS = 0x4D534400; /// /// Type ID for HFS, as set by CrossMac, "MAC\0" /// const uint TypeIDCrossMac = 0x4D414300; /// /// Type ID for 4.2UFS, for BFFS, "BFFS" /// const uint TypeIDBFFS = 0x42464653; /// /// Type ID for Amiga Original File System with multi-user patches, "muF\0" /// const uint TypeIDmuOFS = 0x6D754600; /// /// Type ID for Amiga Fast File System with multi-user patches, "muF\1" /// const uint TypeIDmuFFS = 0x6D754601; /// /// Type ID for Amiga Original File System with international characters and multi-user patches, "muF\2" /// const uint TypeIDmuOFSi = 0x6D754602; /// /// Type ID for Amiga Fast File System with international characters and multi-user patches, "muF\3" /// const uint TypeIDmuFFSi = 0x6D754603; /// /// Type ID for Amiga Original File System with directory cache and multi-user patches, "muF\4" /// const uint TypeIDmuOFSc = 0x6D754604; /// /// Type ID for Amiga Fast File System with directory cache and multi-user patches, "muF\5" /// const uint TypeIDmuFFSc = 0x6D754605; /// /// Type ID for BSD unused, "BSD\0" /// const uint TypeIDOldBSDUnused = 0x42534400; /// /// Type ID for BSD swap, "BSD\1" /// const uint TypeIDOldBSDSwap = 0x42534401; /// /// Type ID for BSD 4.2 FFS, "BSD\7" /// const uint TypeIDOldBSD42FFS = 0x42534407; /// /// Type ID for BSD 4.4 LFS, "BSD\9" /// const uint TypeIDOldBSD44LFS = 0x42534409; /// /// Type ID for NetBSD unused root partition, "NBR\0" /// const uint TypeIDNetBSDRootUnused = 0x4E425200; /// /// Type ID for NetBSD 4.2 FFS root partition, "NBR\7" /// const uint TypeIDNetBSDRoot42FFS = 0x4E425207; /// /// Type ID for NetBSD 4.4 LFS root partition, "NBR\9" /// const uint TypeIDNetBSDRoot44LFS = 0x4E425209; /// /// Type ID for NetBSD unused user partition, "NBR\0" /// const uint TypeIDNetBSDUserUnused = 0x4E425500; /// /// Type ID for NetBSD 4.2 FFS user partition, "NBR\7" /// const uint TypeIDNetBSDUser42FFS = 0x4E425507; /// /// Type ID for NetBSD 4.4 LFS user partition, "NBR\9" /// const uint TypeIDNetBSDUser44LFS = 0x4E425509; /// /// Type ID for NetBSD swap partition /// const uint TypeIDNetBSDSwap = 0x4E425300; /// /// Type ID for Linux filesystem partition, "LNX\0" /// const uint TypeIDLinux = 0x4C4E5800; /// /// Type ID for Linux swap partition, "SWP\0" /// const uint TypeIDLinuxSwap = 0x53575000; /// /// Type ID for RaidFrame partition, "RAID" /// const uint TypeIDRaidFrame = 0x52414944; /// /// Type ID for RaidFrame partition, "RAI\0" /// const uint TypeIDRaidFrame0 = 0x52414900; /// /// No disks to be configured after this one /// const uint FlagsNoDisks = 0x00000001; /// /// No LUNs to be configured after this one /// const uint FlagsNoLUNs = 0x00000002; /// /// No target IDs to be configured after this one /// const uint FlagsNoTargets = 0x00000004; /// /// Don't try to perform reselection with this drive /// const uint FlagsNoReselection = 0x00000008; /// /// Disk identification is valid /// const uint FlagsValidDiskID = 0x00000010; /// /// Controller identification is valid /// const uint FlagsValidControllerID = 0x00000020; /// /// Drive supports synchronous SCSI mode /// const uint FlagsSynchSCSI = 0x00000040; /// /// Partition is bootable /// const uint FlagsBootable = 0x00000001; /// /// Partition should not be mounted automatically /// const uint FlagsNoAutomount = 0x00000002; public AmigaRigidDiskBlock() { Name = "Amiga Rigid Disk Block"; PluginUUID = new Guid("8D72ED97-1854-4170-9CE4-6E8446FD9863"); } /// /// Amiga Rigid Disk Block, header for partitioning scheme /// Can be in any sector from 0 to 15, inclusive /// struct RigidDiskBlock { /// /// "RDSK" /// public uint magic; /// /// Size in longs /// public uint size; /// /// Checksum /// public int checksum; /// /// SCSI target ID, 7 for non-SCSI /// public uint targetID; /// /// Block size in bytes /// public uint block_size; /// /// Flags /// public uint flags; /// /// Pointer to first BadBlockList, 0xFFFFFFFF means last block in device /// public uint badblock_ptr; /// /// Pointer to first PartitionEntry, 0xFFFFFFFF means last block in device /// public uint partition_ptr; /// /// Pointer to first FileSystemHeader, 0xFFFFFFFF means last block in device /// public uint fsheader_ptr; /// /// Optional drive specific init code /// public uint driveinitcode; /// /// Reserved, should be 0xFFFFFFFF /// public uint reserved1; /// /// Reserved, should be 0xFFFFFFFF /// public uint reserved2; /// /// Reserved, should be 0xFFFFFFFF /// public uint reserved3; /// /// Reserved, should be 0xFFFFFFFF /// public uint reserved4; /// /// Reserved, should be 0xFFFFFFFF /// public uint reserved5; /// /// Reserved, should be 0xFFFFFFFF /// public uint reserved6; /// /// Cylinders in drive /// public uint cylinders; /// /// Sectors per track /// public uint spt; /// /// Heads in drive /// public uint heads; /// /// Drive interleave /// public uint interleave; /// /// Cylinder for parking heads /// public uint parking; /// /// Reserved, should be zero /// public uint reserved7; /// /// Reserved, should be zero /// public uint reserved8; /// /// Reserved, should be zero /// public uint reserved9; /// /// Starting cylinder for write precompensation /// public uint writeprecomp; /// /// Starting cylinder for reduced write current /// public uint reducedwrite; /// /// Drive step rate /// public uint steprate; /// /// Reserved, should be zero /// public uint reserved10; /// /// Reserved, should be zero /// public uint reserved11; /// /// Reserved, should be zero /// public uint reserved12; /// /// Reserved, should be zero /// public uint reserved13; /// /// Reserved, should be zero /// public uint reserved14; /// /// Low block of RDB reserved blocks /// public uint RDBBlockLow; /// /// High block of RDB reserved blocks /// public uint RDBBlockHigh; /// /// Low cylinder for partitionable area /// public uint LowCylinder; /// /// High cylinder for partitionable area /// public uint HighCylinder; /// /// Blocks per cylinder /// public uint CylBlocks; /// /// Seconds for head autoparking /// public uint AutoParkSeconds; /// /// Highest block used by RDB /// public uint HighRDSKBlock; /// /// Reserved, should be zero /// public uint reserved15; /// /// Disk vendor, 8 bytes /// public string diskVendor; /// /// Disk product, 16 bytes /// public string diskProduct; /// /// Disk revision, 4 bytes /// public string diskRevision; /// /// Controller vendor, 8 bytes /// public string controllerVendor; /// /// Controller product, 16 bytes /// public string controllerProduct; /// /// Controller revision, 4 bytes /// public string controllerRevision; /// /// Reserved, should be zero /// public uint reserved16; /// /// Reserved, should be zero /// public uint reserved17; /// /// Reserved, should be zero /// public uint reserved18; /// /// Reserved, should be zero /// public uint reserved19; /// /// Reserved, should be zero /// public uint reserved20; /// /// Reserved, should be zero /// public uint reserved21; /// /// Reserved, should be zero /// public uint reserved22; /// /// Reserved, should be zero /// public uint reserved23; /// /// Reserved, should be zero /// public uint reserved24; /// /// Reserved, should be zero /// public uint reserved25; } /// /// Pair for spare blocks /// struct BadBlockEntry { /// /// Bad block pointer /// public uint badBlock; /// /// Replacement block pointer /// public uint goodBlock; } /// /// List of bad blocks and spares /// struct BadBlockList { /// /// "BADB" /// public uint magic; /// /// Size in longs /// public uint size; /// /// Checksum /// public int checksum; /// /// SCSI target ID, 7 for non-SCSI /// public uint targetID; /// /// Pointer for next BadBlockList /// public uint next_ptr; /// /// Reserved /// public uint reserved; /// /// Bad block entries, up to block filling, 8 bytes each /// public BadBlockEntry[] blockPairs; } /// /// DOSEnvVec, used by AmigaDOS /// struct DOSEnvironmentVector { /// /// Size in longs, should be 16, minimum 11 /// public uint size; /// /// Block size in longs /// public uint block_size; /// /// Unknown, 0 /// public uint sec_org; /// /// Heads in drive /// public uint surfaces; /// /// Sectors per block /// public uint spb; /// /// Blocks per track /// public uint bpt; /// /// DOS reserved blocks at start of partition /// public uint reservedblocks; /// /// DOS reserved blocks at end of partition /// public uint prealloc; /// /// Interleave /// public uint interleave; /// /// First cylinder of a partition, inclusive /// public uint lowCylinder; /// /// Last cylinder of a partition, inclusive /// public uint highCylinder; /// /// Buffers, usually 30 /// public uint numBuffer; /// /// Type of memory to allocate for buffers /// public uint bufMemType; /// /// Maximum transfer, usually 0x7FFFFFFF /// public uint maxTransfer; /// /// Address mask to block out certain memory, usually 0xFFFFFFFE /// public uint Mask; /// /// Boot priority /// public uint bootPriority; /// /// Partition type, and filesystem driver identification for AmigaDOS /// public uint dosType; /// /// Default baud rate for SER and AUX handlers /// public uint baud; /// /// Flow control values for SER and AUX handlers /// public uint control; /// /// Since Kickstart 2, how many boot blocks are to be loaded /// public uint bootBlocks; } struct PartitionEntry { /// /// "PART" /// public uint magic; /// /// Size in longs /// public uint size; /// /// Checksum /// public int checksum; /// /// SCSI target ID, 7 for non-SCSI /// public uint targetID; /// /// Pointer to next PartitionEntry /// public uint next_ptr; /// /// Partition flags /// public uint flags; /// /// Reserved /// public uint reserved1; /// /// Reserved /// public uint reserved2; /// /// Preferred flags for OpenDevice() /// public uint devFlags; /// /// Length of drive name /// public uint driveNameLen; /// /// Drive name, 31 bytes /// public string driveName; /// /// Reserved /// public uint reserved3; /// /// Reserved /// public uint reserved4; /// /// Reserved /// public uint reserved5; /// /// Reserved /// public uint reserved6; /// /// Reserved /// public uint reserved7; /// /// Reserved /// public uint reserved8; /// /// Reserved /// public uint reserved9; /// /// Reserved /// public uint reserved10; /// /// Reserved /// public uint reserved11; /// /// Reserved /// public uint reserved12; /// /// Reserved /// public uint reserved13; /// /// Reserved /// public uint reserved14; /// /// Reserved /// public uint reserved15; /// /// Reserved /// public uint reserved16; /// /// Reserved /// public uint reserved17; /// /// DOSEnvVec, more information about partition /// public DOSEnvironmentVector dosEnvVec; } /// /// Device node, mostly useless, except for pointer to first LoadSegment block /// struct DeviceNode { /// /// Device node type, =0 /// public uint type; /// /// DOS task field, =0 /// public uint task; /// /// Unused, =0 /// public uint locked; /// /// Filename handler to LoadSegment, =0 /// public uint handler; /// /// Stack size when starting task, =0 /// public uint stackSize; /// /// Task priority, =0 /// public uint priority; /// /// Startup message, =0 /// public uint startup; /// /// Pointer to first LoadSegment block /// public uint seglist_ptr; /// /// BCPL globabl vector when starting task, =0xFFFFFFFF /// public uint global_vec; } /// /// File system header /// struct FileSystemHeader { /// /// "FSHD" /// public uint magic; /// /// Size in longs, 64 /// public uint size; /// /// Checksum /// public int checksum; /// /// SCSI target ID, 7 for non-SCSI /// public uint targetID; /// /// Pointer to next FileSystemHeader block /// public uint next_ptr; /// /// Flags, unknown /// public uint flags; /// /// Reserved /// public uint reserved1; /// /// Reserved /// public uint reserved2; /// /// Partition type, and filesystem driver identification for AmigaDOS /// public uint dosType; /// /// Filesystem version /// Mask 0xFFFF0000, >>16, major version /// Mask 0x0000FFFF, minor version /// public uint version; /// /// Bits for DeviceNode fields that should be substituted into a standard device node /// public uint patchFlags; /// /// Device node /// public DeviceNode dnode; } /// /// Filesystem code /// struct LoadSegment { /// /// "LSEG" /// public uint magic; /// /// Size in longs /// public uint size; /// /// Checksum /// public int checksum; /// /// SCSI target ID, 7 for non-SCSI /// public uint targetID; /// /// Pointer to next LoadSegment /// public uint next_ptr; /// /// Executable code, with relocation hunks, til end of sector /// public byte[] loadData; } public override bool GetInformation(ImagePlugins.ImagePlugin imagePlugin, out List partitions) { partitions = new List(); BigEndianBitConverter.IsLittleEndian = BitConverter.IsLittleEndian; ulong RDBBlock = 0; bool foundRDB = false; while(RDBBlock < 16 && !foundRDB) { if(imagePlugin.GetSectors() <= RDBBlock) return false; byte[] tmpSector = imagePlugin.ReadSector(RDBBlock); uint magic = BigEndianBitConverter.ToUInt32(tmpSector, 0); DicConsole.DebugWriteLine("Amiga RDB plugin", "Possible magic at block {0} is 0x{1:X8}", RDBBlock, magic); if(magic == RigidDiskBlockMagic) { DicConsole.DebugWriteLine("Amiga RDB plugin", "Found RDB magic at block {0}", RDBBlock); foundRDB = true; break; } RDBBlock++; } if(!foundRDB) return false; byte[] sector; byte[] tmpString; RigidDiskBlock RDB = new RigidDiskBlock(); sector = imagePlugin.ReadSector(RDBBlock); RDB.magic = BigEndianBitConverter.ToUInt32(sector, 0x00); RDB.size = BigEndianBitConverter.ToUInt32(sector, 0x04); RDB.checksum = BigEndianBitConverter.ToInt32(sector, 0x08); RDB.targetID = BigEndianBitConverter.ToUInt32(sector, 0x0C); RDB.block_size = BigEndianBitConverter.ToUInt32(sector, 0x10); RDB.flags = BigEndianBitConverter.ToUInt32(sector, 0x04); RDB.badblock_ptr = BigEndianBitConverter.ToUInt32(sector, 0x18); RDB.partition_ptr = BigEndianBitConverter.ToUInt32(sector, 0x1C); RDB.fsheader_ptr = BigEndianBitConverter.ToUInt32(sector, 0x20); RDB.driveinitcode = BigEndianBitConverter.ToUInt32(sector, 0x24); RDB.reserved1 = BigEndianBitConverter.ToUInt32(sector, 0x28); RDB.reserved2 = BigEndianBitConverter.ToUInt32(sector, 0x2C); RDB.reserved3 = BigEndianBitConverter.ToUInt32(sector, 0x30); RDB.reserved4 = BigEndianBitConverter.ToUInt32(sector, 0x34); RDB.reserved5 = BigEndianBitConverter.ToUInt32(sector, 0x38); RDB.reserved6 = BigEndianBitConverter.ToUInt32(sector, 0x3C); RDB.cylinders = BigEndianBitConverter.ToUInt32(sector, 0x40); RDB.spt = BigEndianBitConverter.ToUInt32(sector, 0x44); RDB.heads = BigEndianBitConverter.ToUInt32(sector, 0x48); RDB.interleave = BigEndianBitConverter.ToUInt32(sector, 0x4C); RDB.parking = BigEndianBitConverter.ToUInt32(sector, 0x50); RDB.reserved7 = BigEndianBitConverter.ToUInt32(sector, 0x54); RDB.reserved8 = BigEndianBitConverter.ToUInt32(sector, 0x58); RDB.reserved9 = BigEndianBitConverter.ToUInt32(sector, 0x5C); RDB.writeprecomp = BigEndianBitConverter.ToUInt32(sector, 0x60); RDB.reducedwrite = BigEndianBitConverter.ToUInt32(sector, 0x64); RDB.steprate = BigEndianBitConverter.ToUInt32(sector, 0x68); RDB.reserved10 = BigEndianBitConverter.ToUInt32(sector, 0x6C); RDB.reserved11 = BigEndianBitConverter.ToUInt32(sector, 0x70); RDB.reserved12 = BigEndianBitConverter.ToUInt32(sector, 0x74); RDB.reserved13 = BigEndianBitConverter.ToUInt32(sector, 0x78); RDB.reserved14 = BigEndianBitConverter.ToUInt32(sector, 0x7C); RDB.RDBBlockLow = BigEndianBitConverter.ToUInt32(sector, 0x80); RDB.RDBBlockHigh = BigEndianBitConverter.ToUInt32(sector, 0x84); RDB.LowCylinder = BigEndianBitConverter.ToUInt32(sector, 0x88); RDB.HighCylinder = BigEndianBitConverter.ToUInt32(sector, 0x8C); RDB.CylBlocks = BigEndianBitConverter.ToUInt32(sector, 0x90); RDB.AutoParkSeconds = BigEndianBitConverter.ToUInt32(sector, 0x94); RDB.HighCylinder = BigEndianBitConverter.ToUInt32(sector, 0x98); RDB.reserved15 = BigEndianBitConverter.ToUInt32(sector, 0x9C); tmpString = new byte[8]; Array.Copy(sector, 0xA0, tmpString, 0, 8); RDB.diskVendor = StringHandlers.SpacePaddedToString(tmpString); tmpString = new byte[16]; Array.Copy(sector, 0xA8, tmpString, 0, 16); RDB.diskProduct = StringHandlers.SpacePaddedToString(tmpString); tmpString = new byte[4]; Array.Copy(sector, 0xB8, tmpString, 0, 4); RDB.diskRevision = StringHandlers.SpacePaddedToString(tmpString); tmpString = new byte[8]; Array.Copy(sector, 0xBC, tmpString, 0, 8); RDB.controllerVendor = StringHandlers.SpacePaddedToString(tmpString); tmpString = new byte[16]; Array.Copy(sector, 0xC4, tmpString, 0, 16); RDB.controllerProduct = StringHandlers.SpacePaddedToString(tmpString); tmpString = new byte[4]; Array.Copy(sector, 0xD4, tmpString, 0, 4); RDB.controllerRevision = StringHandlers.SpacePaddedToString(tmpString); RDB.reserved16 = BigEndianBitConverter.ToUInt32(sector, 0xD8); RDB.reserved17 = BigEndianBitConverter.ToUInt32(sector, 0xDC); RDB.reserved18 = BigEndianBitConverter.ToUInt32(sector, 0xE0); RDB.reserved19 = BigEndianBitConverter.ToUInt32(sector, 0xE4); RDB.reserved20 = BigEndianBitConverter.ToUInt32(sector, 0xE8); RDB.reserved21 = BigEndianBitConverter.ToUInt32(sector, 0xEC); RDB.reserved22 = BigEndianBitConverter.ToUInt32(sector, 0xF0); RDB.reserved23 = BigEndianBitConverter.ToUInt32(sector, 0xF4); RDB.reserved24 = BigEndianBitConverter.ToUInt32(sector, 0xF8); RDB.reserved25 = BigEndianBitConverter.ToUInt32(sector, 0xFC); DicConsole.DebugWriteLine("Amiga RDB plugin", "RDB.magic = 0x{0:X8}", RDB.magic); DicConsole.DebugWriteLine("Amiga RDB plugin", "RDB.size = {0} longs, {1} bytes", RDB.size, RDB.size * 4); DicConsole.DebugWriteLine("Amiga RDB plugin", "RDB.checksum = 0x{0:X8}", RDB.checksum); DicConsole.DebugWriteLine("Amiga RDB plugin", "RDB.targetID = {0}", RDB.targetID); DicConsole.DebugWriteLine("Amiga RDB plugin", "RDB.block_size = {0}", RDB.block_size); DicConsole.DebugWriteLine("Amiga RDB plugin", "RDB.badblock_ptr = {0}", RDB.badblock_ptr); DicConsole.DebugWriteLine("Amiga RDB plugin", "RDB.partition_ptr = {0}", RDB.partition_ptr); DicConsole.DebugWriteLine("Amiga RDB plugin", "RDB.fsheader_ptr = {0}", RDB.fsheader_ptr); DicConsole.DebugWriteLine("Amiga RDB plugin", "RDB.driveinitcode = {0}", RDB.driveinitcode); DicConsole.DebugWriteLine("Amiga RDB plugin", "RDB.reserved1 = 0x{0:X8}", RDB.reserved1); DicConsole.DebugWriteLine("Amiga RDB plugin", "RDB.reserved2 = 0x{0:X8}", RDB.reserved2); DicConsole.DebugWriteLine("Amiga RDB plugin", "RDB.reserved3 = 0x{0:X8}", RDB.reserved3); DicConsole.DebugWriteLine("Amiga RDB plugin", "RDB.reserved4 = 0x{0:X8}", RDB.reserved4); DicConsole.DebugWriteLine("Amiga RDB plugin", "RDB.reserved5 = 0x{0:X8}", RDB.reserved5); DicConsole.DebugWriteLine("Amiga RDB plugin", "RDB.reserved6 = 0x{0:X8}", RDB.reserved6); DicConsole.DebugWriteLine("Amiga RDB plugin", "RDB.cylinders = {0}", RDB.cylinders); DicConsole.DebugWriteLine("Amiga RDB plugin", "RDB.spt = {0}", RDB.spt); DicConsole.DebugWriteLine("Amiga RDB plugin", "RDB.heads = {0}", RDB.heads); DicConsole.DebugWriteLine("Amiga RDB plugin", "RDB.interleave = {0}", RDB.interleave); DicConsole.DebugWriteLine("Amiga RDB plugin", "RDB.parking = {0}", RDB.parking); DicConsole.DebugWriteLine("Amiga RDB plugin", "RDB.reserved7 = 0x{0:X8}", RDB.reserved7); DicConsole.DebugWriteLine("Amiga RDB plugin", "RDB.reserved8 = 0x{0:X8}", RDB.reserved8); DicConsole.DebugWriteLine("Amiga RDB plugin", "RDB.reserved9 = 0x{0:X8}", RDB.reserved9); DicConsole.DebugWriteLine("Amiga RDB plugin", "RDB.writeprecomp = {0}", RDB.writeprecomp); DicConsole.DebugWriteLine("Amiga RDB plugin", "RDB.reducedwrite = {0}", RDB.reducedwrite); DicConsole.DebugWriteLine("Amiga RDB plugin", "RDB.steprate = {0}", RDB.steprate); DicConsole.DebugWriteLine("Amiga RDB plugin", "RDB.reserved10 = 0x{0:X8}", RDB.reserved10); DicConsole.DebugWriteLine("Amiga RDB plugin", "RDB.reserved11 = 0x{0:X8}", RDB.reserved11); DicConsole.DebugWriteLine("Amiga RDB plugin", "RDB.reserved12 = 0x{0:X8}", RDB.reserved12); DicConsole.DebugWriteLine("Amiga RDB plugin", "RDB.reserved13 = 0x{0:X8}", RDB.reserved13); DicConsole.DebugWriteLine("Amiga RDB plugin", "RDB.reserved14 = 0x{0:X8}", RDB.reserved14); DicConsole.DebugWriteLine("Amiga RDB plugin", "RDB.RDBBlockLow = {0}", RDB.RDBBlockLow); DicConsole.DebugWriteLine("Amiga RDB plugin", "RDB.RDBBlockHigh = {0}", RDB.RDBBlockHigh); DicConsole.DebugWriteLine("Amiga RDB plugin", "RDB.LowCylinder = {0}", RDB.LowCylinder); DicConsole.DebugWriteLine("Amiga RDB plugin", "RDB.HighCylinder = {0}", RDB.HighCylinder); DicConsole.DebugWriteLine("Amiga RDB plugin", "RDB.CylBlocks = {0}", RDB.CylBlocks); DicConsole.DebugWriteLine("Amiga RDB plugin", "RDB.AutoParkSeconds = {0}", RDB.AutoParkSeconds); DicConsole.DebugWriteLine("Amiga RDB plugin", "RDB.HighCylinder = {0}", RDB.HighCylinder); DicConsole.DebugWriteLine("Amiga RDB plugin", "RDB.reserved15 = 0x{0:X8}", RDB.reserved15); DicConsole.DebugWriteLine("Amiga RDB plugin", "RDB.diskVendor = \"{0}\"", RDB.diskVendor); DicConsole.DebugWriteLine("Amiga RDB plugin", "RDB.diskProduct = \"{0}\"", RDB.diskProduct); DicConsole.DebugWriteLine("Amiga RDB plugin", "RDB.diskRevision = \"{0}\"", RDB.diskRevision); DicConsole.DebugWriteLine("Amiga RDB plugin", "RDB.controllerVendor = \"{0}\"", RDB.controllerVendor); DicConsole.DebugWriteLine("Amiga RDB plugin", "RDB.controllerProduct = \"{0}\"", RDB.controllerProduct); DicConsole.DebugWriteLine("Amiga RDB plugin", "RDB.controllerRevision = \"{0}\"", RDB.controllerRevision); DicConsole.DebugWriteLine("Amiga RDB plugin", "RDB.reserved16 = 0x{0:X8}", RDB.reserved16); DicConsole.DebugWriteLine("Amiga RDB plugin", "RDB.reserved17 = 0x{0:X8}", RDB.reserved17); DicConsole.DebugWriteLine("Amiga RDB plugin", "RDB.reserved18 = 0x{0:X8}", RDB.reserved18); DicConsole.DebugWriteLine("Amiga RDB plugin", "RDB.reserved19 = 0x{0:X8}", RDB.reserved19); DicConsole.DebugWriteLine("Amiga RDB plugin", "RDB.reserved20 = 0x{0:X8}", RDB.reserved20); DicConsole.DebugWriteLine("Amiga RDB plugin", "RDB.reserved21 = 0x{0:X8}", RDB.reserved21); DicConsole.DebugWriteLine("Amiga RDB plugin", "RDB.reserved22 = 0x{0:X8}", RDB.reserved22); DicConsole.DebugWriteLine("Amiga RDB plugin", "RDB.reserved23 = 0x{0:X8}", RDB.reserved23); DicConsole.DebugWriteLine("Amiga RDB plugin", "RDB.reserved24 = 0x{0:X8}", RDB.reserved24); DicConsole.DebugWriteLine("Amiga RDB plugin", "RDB.reserved25 = 0x{0:X8}", RDB.reserved25); ulong nextBlock; // Reading BadBlock list List BadBlockChain = new List(); nextBlock = RDB.badblock_ptr; while(nextBlock != 0xFFFFFFFF) { DicConsole.DebugWriteLine("Amiga RDB plugin", "Going to block {0} in search of a BadBlock block", nextBlock); sector = imagePlugin.ReadSector(nextBlock); uint magic = BigEndianBitConverter.ToUInt32(sector, 0); if(magic != BadBlockListMagic) break; DicConsole.DebugWriteLine("Amiga RDB plugin", "Found BadBlock block"); BadBlockList chainEntry = new BadBlockList(); chainEntry.magic = BigEndianBitConverter.ToUInt32(sector, 0x00); chainEntry.size = BigEndianBitConverter.ToUInt32(sector, 0x04); chainEntry.checksum = BigEndianBitConverter.ToInt32(sector, 0x08); chainEntry.targetID = BigEndianBitConverter.ToUInt32(sector, 0x0C); chainEntry.next_ptr = BigEndianBitConverter.ToUInt32(sector, 0x10); chainEntry.reserved = BigEndianBitConverter.ToUInt32(sector, 0x14); ulong entries = (chainEntry.size - 6) / 2; chainEntry.blockPairs = new BadBlockEntry[entries]; DicConsole.DebugWriteLine("Amiga RDB plugin", "chainEntry.magic = 0x{0:X8}", chainEntry.magic); DicConsole.DebugWriteLine("Amiga RDB plugin", "chainEntry.size = {0} longs, {1} bytes", chainEntry.size, chainEntry.size * 4); DicConsole.DebugWriteLine("Amiga RDB plugin", "chainEntry.checksum = 0x{0:X8}", chainEntry.checksum); DicConsole.DebugWriteLine("Amiga RDB plugin", "chainEntry.targetID = {0}", chainEntry.targetID); DicConsole.DebugWriteLine("Amiga RDB plugin", "chainEntry.next_ptr = {0}", chainEntry.next_ptr); DicConsole.DebugWriteLine("Amiga RDB plugin", "chainEntry.reserved = 0x{0:X8}", chainEntry.reserved); for(ulong i = 0; i < entries; i++) { chainEntry.blockPairs[i].badBlock = BigEndianBitConverter.ToUInt32(sector, (int)(0x18 + i * 8 + 0)); chainEntry.blockPairs[i].goodBlock = BigEndianBitConverter.ToUInt32(sector, (int)(0x18 + i * 8 + 4)); DicConsole.DebugWriteLine("Amiga RDB plugin", "Bad block at {0} replaced with good block at {1}", chainEntry.blockPairs[i].badBlock, chainEntry.blockPairs[i].goodBlock); } BadBlockChain.Add(chainEntry); nextBlock = chainEntry.next_ptr; } // Reading BadBlock list List PartitionEntries = new List(); nextBlock = RDB.partition_ptr; while(nextBlock != 0xFFFFFFFF) { DicConsole.DebugWriteLine("Amiga RDB plugin", "Going to block {0} in search of a PartitionEntry block", nextBlock); sector = imagePlugin.ReadSector(nextBlock); uint magic = BigEndianBitConverter.ToUInt32(sector, 0); if(magic != PartitionBlockMagic) break; DicConsole.DebugWriteLine("Amiga RDB plugin", "Found PartitionEntry block"); PartitionEntry partEntry = new PartitionEntry(); partEntry.dosEnvVec = new DOSEnvironmentVector(); byte[] driveName = new byte[32]; partEntry.magic = BigEndianBitConverter.ToUInt32(sector, 0x00); partEntry.size = BigEndianBitConverter.ToUInt32(sector, 0x04); partEntry.checksum = BigEndianBitConverter.ToInt32(sector, 0x08); partEntry.targetID = BigEndianBitConverter.ToUInt32(sector, 0x0C); partEntry.next_ptr = BigEndianBitConverter.ToUInt32(sector, 0x10); partEntry.flags = BigEndianBitConverter.ToUInt32(sector, 0x14); partEntry.reserved1 = BigEndianBitConverter.ToUInt32(sector, 0x18); partEntry.reserved2 = BigEndianBitConverter.ToUInt32(sector, 0x1C); partEntry.devFlags = BigEndianBitConverter.ToUInt32(sector, 0x20); partEntry.driveNameLen = sector[0x24]; Array.Copy(sector, 0x24, driveName, 0, 32); partEntry.driveName = StringHandlers.PascalToString(driveName); partEntry.reserved3 = BigEndianBitConverter.ToUInt32(sector, 0x44); partEntry.reserved4 = BigEndianBitConverter.ToUInt32(sector, 0x48); partEntry.reserved5 = BigEndianBitConverter.ToUInt32(sector, 0x4C); partEntry.reserved6 = BigEndianBitConverter.ToUInt32(sector, 0x50); partEntry.reserved7 = BigEndianBitConverter.ToUInt32(sector, 0x54); partEntry.reserved8 = BigEndianBitConverter.ToUInt32(sector, 0x58); partEntry.reserved9 = BigEndianBitConverter.ToUInt32(sector, 0x5C); partEntry.reserved10 = BigEndianBitConverter.ToUInt32(sector, 0x60); partEntry.reserved11 = BigEndianBitConverter.ToUInt32(sector, 0x64); partEntry.reserved12 = BigEndianBitConverter.ToUInt32(sector, 0x68); partEntry.reserved13 = BigEndianBitConverter.ToUInt32(sector, 0x6C); partEntry.reserved14 = BigEndianBitConverter.ToUInt32(sector, 0x70); partEntry.reserved15 = BigEndianBitConverter.ToUInt32(sector, 0x74); partEntry.reserved16 = BigEndianBitConverter.ToUInt32(sector, 0x78); partEntry.reserved17 = BigEndianBitConverter.ToUInt32(sector, 0x7C); partEntry.dosEnvVec.size = BigEndianBitConverter.ToUInt32(sector, 0x80); partEntry.dosEnvVec.block_size = BigEndianBitConverter.ToUInt32(sector, 0x84); partEntry.dosEnvVec.sec_org = BigEndianBitConverter.ToUInt32(sector, 0x88); partEntry.dosEnvVec.surfaces = BigEndianBitConverter.ToUInt32(sector, 0x8C); partEntry.dosEnvVec.spb = BigEndianBitConverter.ToUInt32(sector, 0x90); partEntry.dosEnvVec.bpt = BigEndianBitConverter.ToUInt32(sector, 0x94); partEntry.dosEnvVec.reservedblocks = BigEndianBitConverter.ToUInt32(sector, 0x98); partEntry.dosEnvVec.prealloc = BigEndianBitConverter.ToUInt32(sector, 0x9C); partEntry.dosEnvVec.interleave = BigEndianBitConverter.ToUInt32(sector, 0xA0); partEntry.dosEnvVec.lowCylinder = BigEndianBitConverter.ToUInt32(sector, 0xA4); partEntry.dosEnvVec.highCylinder = BigEndianBitConverter.ToUInt32(sector, 0xA8); partEntry.dosEnvVec.numBuffer = BigEndianBitConverter.ToUInt32(sector, 0xAC); partEntry.dosEnvVec.bufMemType = BigEndianBitConverter.ToUInt32(sector, 0xB0); partEntry.dosEnvVec.maxTransfer = BigEndianBitConverter.ToUInt32(sector, 0xB4); partEntry.dosEnvVec.Mask = BigEndianBitConverter.ToUInt32(sector, 0xB8); partEntry.dosEnvVec.bootPriority = BigEndianBitConverter.ToUInt32(sector, 0xBC); partEntry.dosEnvVec.dosType = BigEndianBitConverter.ToUInt32(sector, 0xC0); partEntry.dosEnvVec.baud = BigEndianBitConverter.ToUInt32(sector, 0xC4); partEntry.dosEnvVec.control = BigEndianBitConverter.ToUInt32(sector, 0xC8); partEntry.dosEnvVec.bootBlocks = BigEndianBitConverter.ToUInt32(sector, 0xCC); DicConsole.DebugWriteLine("Amiga RDB plugin", "partEntry.magic = 0x{0:X8}", partEntry.magic); DicConsole.DebugWriteLine("Amiga RDB plugin", "partEntry.size = {0} longs, {1} bytes", partEntry.size, partEntry.size * 4); DicConsole.DebugWriteLine("Amiga RDB plugin", "partEntry.checksum = 0x{0:X8}", partEntry.checksum); DicConsole.DebugWriteLine("Amiga RDB plugin", "partEntry.targetID = {0}", partEntry.targetID); DicConsole.DebugWriteLine("Amiga RDB plugin", "partEntry.next_ptr = {0}", partEntry.next_ptr); DicConsole.DebugWriteLine("Amiga RDB plugin", "partEntry.flags = 0x{0:X8}", partEntry.flags); DicConsole.DebugWriteLine("Amiga RDB plugin", "partEntry.reserved1 = 0x{0:X8}", partEntry.reserved1); DicConsole.DebugWriteLine("Amiga RDB plugin", "partEntry.reserved2 = 0x{0:X8}", partEntry.reserved2); DicConsole.DebugWriteLine("Amiga RDB plugin", "partEntry.devFlags = 0x{0:X8}", partEntry.devFlags); DicConsole.DebugWriteLine("Amiga RDB plugin", "partEntry.driveNameLen = {0}", partEntry.driveNameLen); DicConsole.DebugWriteLine("Amiga RDB plugin", "partEntry.driveName = \"{0}\"", partEntry.driveName); DicConsole.DebugWriteLine("Amiga RDB plugin", "partEntry.reserved3 = 0x{0:X8}", partEntry.reserved3); DicConsole.DebugWriteLine("Amiga RDB plugin", "partEntry.reserved4 = 0x{0:X8}", partEntry.reserved4); DicConsole.DebugWriteLine("Amiga RDB plugin", "partEntry.reserved5 = 0x{0:X8}", partEntry.reserved5); DicConsole.DebugWriteLine("Amiga RDB plugin", "partEntry.reserved6 = 0x{0:X8}", partEntry.reserved6); DicConsole.DebugWriteLine("Amiga RDB plugin", "partEntry.reserved7 = 0x{0:X8}", partEntry.reserved7); DicConsole.DebugWriteLine("Amiga RDB plugin", "partEntry.reserved8 = 0x{0:X8}", partEntry.reserved8); DicConsole.DebugWriteLine("Amiga RDB plugin", "partEntry.reserved9 = 0x{0:X8}", partEntry.reserved9); DicConsole.DebugWriteLine("Amiga RDB plugin", "partEntry.reserved10 = 0x{0:X8}", partEntry.reserved10); DicConsole.DebugWriteLine("Amiga RDB plugin", "partEntry.reserved11 = 0x{0:X8}", partEntry.reserved11); DicConsole.DebugWriteLine("Amiga RDB plugin", "partEntry.reserved12 = 0x{0:X8}", partEntry.reserved12); DicConsole.DebugWriteLine("Amiga RDB plugin", "partEntry.reserved13 = 0x{0:X8}", partEntry.reserved13); DicConsole.DebugWriteLine("Amiga RDB plugin", "partEntry.reserved14 = 0x{0:X8}", partEntry.reserved14); DicConsole.DebugWriteLine("Amiga RDB plugin", "partEntry.reserved15 = 0x{0:X8}", partEntry.reserved15); DicConsole.DebugWriteLine("Amiga RDB plugin", "partEntry.reserved16 = 0x{0:X8}", partEntry.reserved16); DicConsole.DebugWriteLine("Amiga RDB plugin", "partEntry.reserved17 = 0x{0:X8}", partEntry.reserved17); DicConsole.DebugWriteLine("Amiga RDB plugin", "partEntry.dosEnvVec.size = {0} longs, {1} bytes", partEntry.dosEnvVec.size, partEntry.dosEnvVec.size * 4); DicConsole.DebugWriteLine("Amiga RDB plugin", "partEntry.dosEnvVec.block_size = {0} longs, {1} bytes", partEntry.dosEnvVec.block_size, partEntry.dosEnvVec.block_size * 4); DicConsole.DebugWriteLine("Amiga RDB plugin", "partEntry.dosEnvVec.sec_org = 0x{0:X8}", partEntry.dosEnvVec.sec_org); DicConsole.DebugWriteLine("Amiga RDB plugin", "partEntry.dosEnvVec.surfaces = {0}", partEntry.dosEnvVec.surfaces); DicConsole.DebugWriteLine("Amiga RDB plugin", "partEntry.dosEnvVec.spb = {0}", partEntry.dosEnvVec.spb); DicConsole.DebugWriteLine("Amiga RDB plugin", "partEntry.dosEnvVec.bpt = {0}", partEntry.dosEnvVec.bpt); DicConsole.DebugWriteLine("Amiga RDB plugin", "partEntry.dosEnvVec.reservedblocks = {0}", partEntry.dosEnvVec.reservedblocks); DicConsole.DebugWriteLine("Amiga RDB plugin", "partEntry.dosEnvVec.prealloc = {0}", partEntry.dosEnvVec.prealloc); DicConsole.DebugWriteLine("Amiga RDB plugin", "partEntry.dosEnvVec.interleave = {0}", partEntry.dosEnvVec.interleave); DicConsole.DebugWriteLine("Amiga RDB plugin", "partEntry.dosEnvVec.lowCylinder = {0}", partEntry.dosEnvVec.lowCylinder); DicConsole.DebugWriteLine("Amiga RDB plugin", "partEntry.dosEnvVec.highCylinder = {0}", partEntry.dosEnvVec.highCylinder); DicConsole.DebugWriteLine("Amiga RDB plugin", "partEntry.dosEnvVec.numBuffer = {0}", partEntry.dosEnvVec.numBuffer); DicConsole.DebugWriteLine("Amiga RDB plugin", "partEntry.dosEnvVec.bufMemType = {0}", partEntry.dosEnvVec.bufMemType); DicConsole.DebugWriteLine("Amiga RDB plugin", "partEntry.dosEnvVec.maxTransfer = {0}", partEntry.dosEnvVec.maxTransfer); DicConsole.DebugWriteLine("Amiga RDB plugin", "partEntry.dosEnvVec.Mask = 0x{0:X8}", partEntry.dosEnvVec.Mask); DicConsole.DebugWriteLine("Amiga RDB plugin", "partEntry.dosEnvVec.bootPriority = {0}", partEntry.dosEnvVec.bootPriority); DicConsole.DebugWriteLine("Amiga RDB plugin", "partEntry.dosEnvVec.dosType = {0}", AmigaDOSTypeToString(partEntry.dosEnvVec.dosType, true)); DicConsole.DebugWriteLine("Amiga RDB plugin", "partEntry.dosEnvVec.baud = {0}", partEntry.dosEnvVec.baud); DicConsole.DebugWriteLine("Amiga RDB plugin", "partEntry.dosEnvVec.control = 0x{0:X8}", partEntry.dosEnvVec.control); DicConsole.DebugWriteLine("Amiga RDB plugin", "partEntry.dosEnvVec.bootBlocks = {0}", partEntry.dosEnvVec.bootBlocks); PartitionEntries.Add(partEntry); nextBlock = partEntry.next_ptr; } // Reading BadBlock list List FSHDEntries = new List(); List SegmentEntries = new List(); nextBlock = RDB.fsheader_ptr; while(nextBlock != 0xFFFFFFFF) { DicConsole.DebugWriteLine("Amiga RDB plugin", "Going to block {0} in search of a FileSystemHeader block", nextBlock); sector = imagePlugin.ReadSector(nextBlock); uint magic = BigEndianBitConverter.ToUInt32(sector, 0); if(magic != FilesystemHeaderMagic) break; DicConsole.DebugWriteLine("Amiga RDB plugin", "Found FileSystemHeader block"); FileSystemHeader FSHD = new FileSystemHeader(); FSHD.dnode = new DeviceNode(); FSHD.magic = BigEndianBitConverter.ToUInt32(sector, 0x00); FSHD.size = BigEndianBitConverter.ToUInt32(sector, 0x04); FSHD.checksum = BigEndianBitConverter.ToInt32(sector, 0x08); FSHD.targetID = BigEndianBitConverter.ToUInt32(sector, 0x0C); FSHD.next_ptr = BigEndianBitConverter.ToUInt32(sector, 0x10); FSHD.flags = BigEndianBitConverter.ToUInt32(sector, 0x14); FSHD.reserved1 = BigEndianBitConverter.ToUInt32(sector, 0x18); FSHD.reserved2 = BigEndianBitConverter.ToUInt32(sector, 0x1C); FSHD.dosType = BigEndianBitConverter.ToUInt32(sector, 0x20); FSHD.version = BigEndianBitConverter.ToUInt32(sector, 0x24); FSHD.patchFlags = BigEndianBitConverter.ToUInt32(sector, 0x28); FSHD.dnode.type = BigEndianBitConverter.ToUInt32(sector, 0x2C); FSHD.dnode.task = BigEndianBitConverter.ToUInt32(sector, 0x30); FSHD.dnode.locked = BigEndianBitConverter.ToUInt32(sector, 0x34); FSHD.dnode.handler = BigEndianBitConverter.ToUInt32(sector, 0x38); FSHD.dnode.stackSize = BigEndianBitConverter.ToUInt32(sector, 0x3C); FSHD.dnode.priority = BigEndianBitConverter.ToUInt32(sector, 0x40); FSHD.dnode.startup = BigEndianBitConverter.ToUInt32(sector, 0x44); FSHD.dnode.seglist_ptr = BigEndianBitConverter.ToUInt32(sector, 0x48); FSHD.dnode.global_vec = BigEndianBitConverter.ToUInt32(sector, 0x4C); DicConsole.DebugWriteLine("Amiga RDB plugin", "FSHD.magic = 0x{0:X8}", FSHD.magic); DicConsole.DebugWriteLine("Amiga RDB plugin", "FSHD.size = {0} longs, {1} bytes", FSHD.size, FSHD.size * 4); DicConsole.DebugWriteLine("Amiga RDB plugin", "FSHD.checksum = 0x{0:X8}", FSHD.checksum); DicConsole.DebugWriteLine("Amiga RDB plugin", "FSHD.targetID = {0}", FSHD.targetID); DicConsole.DebugWriteLine("Amiga RDB plugin", "FSHD.next_ptr = {0}", FSHD.next_ptr); DicConsole.DebugWriteLine("Amiga RDB plugin", "FSHD.flags = 0x{0:X8}", FSHD.flags); DicConsole.DebugWriteLine("Amiga RDB plugin", "FSHD.reserved1 = 0x{0:X8}", FSHD.reserved1); DicConsole.DebugWriteLine("Amiga RDB plugin", "FSHD.reserved2 = 0x{0:X8}", FSHD.reserved2); DicConsole.DebugWriteLine("Amiga RDB plugin", "FSHD.dosType = {0}", AmigaDOSTypeToString(FSHD.dosType)); DicConsole.DebugWriteLine("Amiga RDB plugin", "FSHD.version = {0:D2}.{1:D2} (0x{2:X8})", (FSHD.version & 0xFFFF0000) >> 16, FSHD.version & 0xFFFF, FSHD.version); DicConsole.DebugWriteLine("Amiga RDB plugin", "FSHD.patchFlags = 0x{0:X8}", FSHD.patchFlags); DicConsole.DebugWriteLine("Amiga RDB plugin", "FSHD.dnode.type = {0}", FSHD.dnode.type); DicConsole.DebugWriteLine("Amiga RDB plugin", "FSHD.dnode.task = {0}", FSHD.dnode.task); DicConsole.DebugWriteLine("Amiga RDB plugin", "FSHD.dnode.locked = {0}", FSHD.dnode.locked); DicConsole.DebugWriteLine("Amiga RDB plugin", "FSHD.dnode.handler = {0}", FSHD.dnode.handler); DicConsole.DebugWriteLine("Amiga RDB plugin", "FSHD.dnode.stackSize = {0}", FSHD.dnode.stackSize); DicConsole.DebugWriteLine("Amiga RDB plugin", "FSHD.dnode.priority = {0}", FSHD.dnode.priority); DicConsole.DebugWriteLine("Amiga RDB plugin", "FSHD.dnode.startup = {0}", FSHD.dnode.startup); DicConsole.DebugWriteLine("Amiga RDB plugin", "FSHD.dnode.seglist_ptr = {0}", FSHD.dnode.seglist_ptr); DicConsole.DebugWriteLine("Amiga RDB plugin", "FSHD.dnode.global_vec = 0x{0:X8}", FSHD.dnode.global_vec); nextBlock = FSHD.dnode.seglist_ptr; bool thereAreLoadSegments = false; Checksums.SHA1Context sha1Ctx = new Checksums.SHA1Context(); sha1Ctx.Init(); while(nextBlock != 0xFFFFFFFF) { DicConsole.DebugWriteLine("Amiga RDB plugin", "Going to block {0} in search of a LoadSegment block", nextBlock); sector = imagePlugin.ReadSector(nextBlock); uint magicSeg = BigEndianBitConverter.ToUInt32(sector, 0); if(magicSeg != LoadSegMagic) break; DicConsole.DebugWriteLine("Amiga RDB plugin", "Found LoadSegment block"); thereAreLoadSegments = true; LoadSegment loadSeg = new LoadSegment(); loadSeg.magic = BigEndianBitConverter.ToUInt32(sector, 0x00); loadSeg.size = BigEndianBitConverter.ToUInt32(sector, 0x04); loadSeg.checksum = BigEndianBitConverter.ToInt32(sector, 0x08); loadSeg.targetID = BigEndianBitConverter.ToUInt32(sector, 0x0C); loadSeg.next_ptr = BigEndianBitConverter.ToUInt32(sector, 0x10); loadSeg.loadData = new byte[(loadSeg.size - 5) * 4]; Array.Copy(sector, 0x14, loadSeg.loadData, 0, (loadSeg.size - 5) * 4); DicConsole.DebugWriteLine("Amiga RDB plugin", "loadSeg.magic = 0x{0:X8}", loadSeg.magic); DicConsole.DebugWriteLine("Amiga RDB plugin", "loadSeg.size = {0} longs, {1} bytes", loadSeg.size, loadSeg.size * 4); DicConsole.DebugWriteLine("Amiga RDB plugin", "loadSeg.checksum = 0x{0:X8}", loadSeg.checksum); DicConsole.DebugWriteLine("Amiga RDB plugin", "loadSeg.targetID = {0}", loadSeg.targetID); DicConsole.DebugWriteLine("Amiga RDB plugin", "loadSeg.next_ptr = {0}", loadSeg.next_ptr); SegmentEntries.Add(loadSeg); nextBlock = loadSeg.next_ptr; sha1Ctx.Update(loadSeg.loadData); } if(thereAreLoadSegments) { string loadSegSHA1 = sha1Ctx.End(); DicConsole.DebugWriteLine("Amiga RDB plugin", "LoadSegment data SHA1: {0}", loadSegSHA1); } FSHDEntries.Add(FSHD); nextBlock = FSHD.next_ptr; } ulong sequence = 0; foreach(PartitionEntry RDBEntry in PartitionEntries) { CommonTypes.Partition entry = new CommonTypes.Partition(); entry.PartitionDescription = AmigaDOSTypeToDescriptionString(RDBEntry.dosEnvVec.dosType); entry.PartitionName = RDBEntry.driveName; entry.PartitionSequence = sequence; entry.PartitionSectors = (RDBEntry.dosEnvVec.highCylinder + 1 - RDBEntry.dosEnvVec.lowCylinder) * RDBEntry.dosEnvVec.surfaces * RDBEntry.dosEnvVec.bpt; entry.PartitionStartSector = RDBEntry.dosEnvVec.lowCylinder * RDBEntry.dosEnvVec.surfaces * RDBEntry.dosEnvVec.bpt; entry.PartitionStart = entry.PartitionStartSector * RDB.block_size; entry.PartitionLength = entry.PartitionSectors * RDB.block_size; entry.PartitionType = AmigaDOSTypeToString(RDBEntry.dosEnvVec.dosType); partitions.Add(entry); sequence++; } return true; } static string AmigaDOSTypeToDescriptionString(uint AmigaDOSType) { switch(AmigaDOSType) { case TypeIDOFS: return "Amiga Original File System"; case TypeIDFFS: return "Amiga Fast File System"; case TypeIDOFSi: return "Amiga Original File System with international characters"; case TypeIDFFSi: return "Amiga Fast File System with international characters"; case TypeIDOFSc: return "Amiga Original File System with directory cache"; case TypeIDFFSc: return "Amiga Fast File System with directory cache"; case TypeIDOFS2: return "Amiga Original File System with long filenames"; case TypeIDFFS2: return "Amiga Fast File System with long filenames"; case TypeIDAMIXSysV: return "Amiga UNIX System V filesystem"; case TypeIDAMIXBoot: return "Amiga UNIX boot filesystem"; case TypeIDAMIXFFS: return "Amiga UNIX BSD filesystem"; case TypeIDAMIXReserved: return "Amiga UNIX Reserved partition (swap)"; case TypeIDPFS: case TypeIDPFS2: case TypeIDPFSm: case TypeIDAFS: return "ProfessionalFileSystem"; case TypeIDSFS: return "SmartFileSystem v1"; case TypeIDSFS2: return "SmartFileSystem v2"; case TypeIDJXFS: return "JXFS"; case TypeIDCrossDOS: return "FAT, as set by CrossDOS"; case TypeIDCrossMac: return "HFS, as set by CrossMac"; case TypeIDBFFS: return "4.2UFS, for BFFS"; case TypeIDmuOFS: return "Amiga Original File System with multi-user patches"; case TypeIDmuFFS: return "Amiga Fast File System with multi-user patches"; case TypeIDmuOFSi: return "Amiga Original File System with international characters and multi-user patches"; case TypeIDmuFFSi: return "Amiga Fast File System with international characters and multi-user patches"; case TypeIDmuOFSc: return "Amiga Original File System with directory cache and multi-user patches"; case TypeIDmuFFSc: return "Amiga Fast File System with directory cache and multi-user patches"; case TypeIDOldBSDUnused: return "BSD unused"; case TypeIDOldBSDSwap: return "BSD swap"; case TypeIDOldBSD42FFS: return "BSD 4.2 FFS"; case TypeIDOldBSD44LFS: return "BSD 4.4 LFS"; case TypeIDNetBSDRootUnused: return "NetBSD unused root partition"; case TypeIDNetBSDRoot42FFS: return "NetBSD 4.2 FFS root partition"; case TypeIDNetBSDRoot44LFS: return "NetBSD 4.4 LFS root partition"; case TypeIDNetBSDUserUnused: return "NetBSD unused user partition"; case TypeIDNetBSDUser42FFS: return "NetBSD 4.2 FFS user partition"; case TypeIDNetBSDUser44LFS: return "NetBSD 4.4 LFS user partition"; case TypeIDNetBSDSwap: return "NetBSD swap partition"; case TypeIDLinux: return "Linux filesystem partition"; case TypeIDLinuxSwap: return "Linux swap partition"; case TypeIDRaidFrame: case TypeIDRaidFrame0: return "RaidFrame partition"; default: { if((AmigaDOSType & TypeIDOFS) == TypeIDOFS) return string.Format("Unknown Amiga DOS filesystem type {0}", AmigaDOSTypeToString(AmigaDOSType)); if((AmigaDOSType & TypeIDAMIXSysV) == TypeIDAMIXSysV) return string.Format("Unknown Amiga UNIX filesystem type {0}", AmigaDOSTypeToString(AmigaDOSType)); if((AmigaDOSType & 0x50465300) == 0x50465300 || (AmigaDOSType & 0x41465300) == 0x41465300) return string.Format("Unknown ProfessionalFileSystem type {0}", AmigaDOSTypeToString(AmigaDOSType)); if((AmigaDOSType & TypeIDSFS) == TypeIDSFS) return string.Format("Unknown SmartFileSystem type {0}", AmigaDOSTypeToString(AmigaDOSType)); if((AmigaDOSType & TypeIDmuOFS) == TypeIDmuOFS) return string.Format("Unknown Amiga DOS multi-user filesystem type {0}", AmigaDOSTypeToString(AmigaDOSType)); if((AmigaDOSType & TypeIDOldBSDUnused) == TypeIDOldBSDUnused) return string.Format("Unknown BSD filesystem type {0}", AmigaDOSTypeToString(AmigaDOSType)); if((AmigaDOSType & TypeIDNetBSDRootUnused) == TypeIDNetBSDRootUnused) return string.Format("Unknown NetBSD root filesystem type {0}", AmigaDOSTypeToString(AmigaDOSType)); if((AmigaDOSType & TypeIDNetBSDUserUnused) == TypeIDNetBSDUserUnused) return string.Format("Unknown NetBSD user filesystem type {0}", AmigaDOSTypeToString(AmigaDOSType)); if((AmigaDOSType & TypeIDNetBSDSwap) == TypeIDNetBSDSwap) return string.Format("Unknown NetBSD swap filesystem type {0}", AmigaDOSTypeToString(AmigaDOSType)); if((AmigaDOSType & TypeIDLinux) == TypeIDLinux || (AmigaDOSType & TypeIDLinuxSwap) == TypeIDLinuxSwap) return string.Format("Unknown Linux filesystem type {0}", AmigaDOSTypeToString(AmigaDOSType)); return string.Format("Unknown partition type {0}", AmigaDOSTypeToString(AmigaDOSType)); } } } static string AmigaDOSTypeToString(uint AmigaDOSType) { return AmigaDOSTypeToString(AmigaDOSType, true); } static string AmigaDOSTypeToString(uint AmigaDOSType, bool quoted) { byte[] textPart = new byte[3]; string textPartString; textPart[0] = (byte)((AmigaDOSType & 0xFF000000) >> 24); textPart[1] = (byte)((AmigaDOSType & 0x00FF0000) >> 16); textPart[2] = (byte)((AmigaDOSType & 0x0000FF00) >> 8); textPartString = Encoding.ASCII.GetString(textPart); return quoted ? string.Format("\"{0}\\{1}\"", textPartString, AmigaDOSType & 0xFF) : string.Format("{0}\\{1}", textPartString, AmigaDOSType & 0xFF); } } }