diff --git a/DiscImageChef.Partitions/AppleMap.cs b/DiscImageChef.Partitions/AppleMap.cs
index 2c387c24c..e5d9a5ca4 100644
--- a/DiscImageChef.Partitions/AppleMap.cs
+++ b/DiscImageChef.Partitions/AppleMap.cs
@@ -34,7 +34,7 @@ using System;
using System.Text;
using System.Collections.Generic;
using DiscImageChef.Console;
-
+using System.Runtime.InteropServices;
namespace DiscImageChef.PartPlugins
{
@@ -42,12 +42,14 @@ namespace DiscImageChef.PartPlugins
// Constants from image testing
public class AppleMap : PartPlugin
{
- // "ER"
- const ushort APM_MAGIC = 0x4552;
- // "PM"
- const ushort APM_ENTRY = 0x504D;
- // "TS", old entry magic
- const ushort APM_OLDENT = 0x5453;
+ /// "ER", driver descriptor magic
+ const ushort DDM_MAGIC = 0x4552;
+ /// "PM", new entry magic
+ const ushort APM_MAGIC = 0x504D;
+ /// "TS", old map magic
+ const ushort APM_MAGIC_OLD = 0x5453;
+ /// Old indicator for HFS partition, "TFS1"
+ const uint HFS_MAGIC_OLD = 0x54465331;
public AppleMap()
{
@@ -57,7 +59,6 @@ namespace DiscImageChef.PartPlugins
public override bool GetInformation(ImagePlugins.ImagePlugin imagePlugin, out List partitions)
{
- ulong apm_entries;
uint sector_size;
if(imagePlugin.GetSectorSize() == 2352 || imagePlugin.GetSectorSize() == 2448)
@@ -67,249 +68,378 @@ namespace DiscImageChef.PartPlugins
partitions = new List();
- AppleMapBootEntry APMB = new AppleMapBootEntry();
- AppleMapPartitionEntry APMEntry;
+ byte[] ddm_sector = imagePlugin.ReadSector(0);
+ AppleDriverDescriptorMap ddm;
- byte[] APMB_sector = imagePlugin.ReadSector(0);
+ ushort max_drivers = 61;
- BigEndianBitConverter.IsLittleEndian = BitConverter.IsLittleEndian;
-
- APMB.signature = BigEndianBitConverter.ToUInt16(APMB_sector, 0x00);
- APMB.sector_size = BigEndianBitConverter.ToUInt16(APMB_sector, 0x02);
- APMB.sectors = BigEndianBitConverter.ToUInt32(APMB_sector, 0x04);
- APMB.reserved1 = BigEndianBitConverter.ToUInt16(APMB_sector, 0x08);
- APMB.reserved2 = BigEndianBitConverter.ToUInt16(APMB_sector, 0x0A);
- APMB.reserved3 = BigEndianBitConverter.ToUInt32(APMB_sector, 0x0C);
- APMB.driver_entries = BigEndianBitConverter.ToUInt16(APMB_sector, 0x10);
- APMB.first_driver_blk = BigEndianBitConverter.ToUInt32(APMB_sector, 0x12);
- APMB.driver_size = BigEndianBitConverter.ToUInt16(APMB_sector, 0x16);
- APMB.operating_system = BigEndianBitConverter.ToUInt16(APMB_sector, 0x18);
-
- DicConsole.DebugWriteLine("Apple Partition Map plugin", "APMB.signature = {0:X4}", APMB.signature);
- DicConsole.DebugWriteLine("Apple Partition Map plugin", "APMB.sector_size = {0}", APMB.sector_size);
- DicConsole.DebugWriteLine("Apple Partition Map plugin", "APMB.sectors = {0}", APMB.sectors);
- DicConsole.DebugWriteLine("Apple Partition Map plugin", "APMB.reserved1 = {0:X4}", APMB.reserved1);
- DicConsole.DebugWriteLine("Apple Partition Map plugin", "APMB.reserved2 = {0:X4}", APMB.reserved2);
- DicConsole.DebugWriteLine("Apple Partition Map plugin", "APMB.reserved3 = {0:X8}", APMB.reserved3);
- DicConsole.DebugWriteLine("Apple Partition Map plugin", "APMB.driver_entries = {0}", APMB.driver_entries);
- DicConsole.DebugWriteLine("Apple Partition Map plugin", "APMB.first_driver_blk = {0}", APMB.first_driver_blk);
- DicConsole.DebugWriteLine("Apple Partition Map plugin", "APMB.driver_size = {0}", APMB.driver_size);
- DicConsole.DebugWriteLine("Apple Partition Map plugin", "APMB.operating_system = {0}", APMB.operating_system);
-
- ulong first_sector = 0;
-
- if(APMB.signature == APM_MAGIC) // APM boot block found, APM starts in next sector
- first_sector = 1;
-
- // Read first entry
- byte[] APMEntry_sector;
- bool APMFromHDDOnCD = false;
-
- if(sector_size == 2048)
+ if(sector_size == 256)
{
- APMEntry_sector = Read2048SectorAs512(imagePlugin, first_sector);
- APMEntry = DecodeAPMEntry(APMEntry_sector);
+ byte[] tmp = new byte[512];
+ Array.Copy(ddm_sector, 0, tmp, 0, 256);
+ ddm_sector = tmp;
+ max_drivers = 29;
+ }
+ else if(sector_size < 256)
+ return false;
+
+ ddm = BigEndianMarshal.ByteArrayToStructureBigEndian(ddm_sector);
- if(APMEntry.signature == APM_ENTRY || APMEntry.signature == APM_OLDENT)
+ DicConsole.DebugWriteLine("AppleMap Plugin", "ddm.sbSig = 0x{0:X4}", ddm.sbSig);
+ DicConsole.DebugWriteLine("AppleMap Plugin", "ddm.sbBlockSize = {0}", ddm.sbBlockSize);
+ DicConsole.DebugWriteLine("AppleMap Plugin", "ddm.sbBlocks = {0}", ddm.sbBlocks);
+ DicConsole.DebugWriteLine("AppleMap Plugin", "ddm.sbDevType = {0}", ddm.sbDevType);
+ DicConsole.DebugWriteLine("AppleMap Plugin", "ddm.sbDevId = {0}", ddm.sbDevId);
+ DicConsole.DebugWriteLine("AppleMap Plugin", "ddm.sbData = 0x{0:X8}", ddm.sbData);
+ DicConsole.DebugWriteLine("AppleMap Plugin", "ddm.sbDrvrCount = {0}", ddm.sbDrvrCount);
+
+ if(ddm.sbSig != DDM_MAGIC)
+ return false;
+
+ uint sequence = 0;
+
+ if(ddm.sbDrvrCount < max_drivers)
+ {
+ ddm.sbMap = new AppleDriverEntry[ddm.sbDrvrCount];
+ for(int i = 0; i < ddm.sbDrvrCount; i++)
{
- sector_size = 512;
- APMFromHDDOnCD = true;
- DicConsole.DebugWriteLine("Apple Partition Map plugin", "PM sector size is 512 bytes, but device's 2048");
+ byte[] tmp = new byte[8];
+ Array.Copy(ddm_sector, 18 + i * 8, tmp, 0, 8);
+ ddm.sbMap[i] = BigEndianMarshal.ByteArrayToStructureBigEndian(tmp);
+ DicConsole.DebugWriteLine("AppleMap Plugin", "ddm.sbMap[{1}].ddBlock = {0}", ddm.sbMap[i].ddBlock, i);
+ DicConsole.DebugWriteLine("AppleMap Plugin", "ddm.sbMap[{1}].ddSize = {0}", ddm.sbMap[i].ddSize, i);
+ DicConsole.DebugWriteLine("AppleMap Plugin", "ddm.sbMap[{1}].ddType = {0}", ddm.sbMap[i].ddType, i);
+
+ CommonTypes.Partition part = new CommonTypes.Partition()
+ {
+ PartitionLength = (ulong)(ddm.sbMap[i].ddSize * 512),
+ PartitionSectors = (ulong)((ddm.sbMap[i].ddSize * 512) / sector_size),
+ PartitionSequence = sequence,
+ PartitionStart = ddm.sbMap[i].ddBlock * sector_size,
+ PartitionStartSector = ddm.sbMap[i].ddBlock,
+ PartitionType = "Apple_Driver"
+ };
+
+ partitions.Add(part);
+
+ sequence++;
+ }
+ }
+
+ byte[] part_sector = imagePlugin.ReadSector(1);
+ AppleOldDevicePartitionMap old_map = BigEndianMarshal.ByteArrayToStructureBigEndian(part_sector);
+
+ // This is the easy one, no sector size mixing
+ if(old_map.pdSig == APM_MAGIC_OLD)
+ {
+ for(int i = 2; i < part_sector.Length; i+=12)
+ {
+ byte[] tmp = new byte[12];
+ Array.Copy(part_sector, i, tmp, 0, 12);
+ AppleMapOldPartitionEntry old_entry = BigEndianMarshal.ByteArrayToStructureBigEndian(tmp);
+ DicConsole.DebugWriteLine("AppleMap Plugin", "old_map.sbMap[{1}].pdStart = {0}", old_entry.pdStart, (i - 2) / 12);
+ DicConsole.DebugWriteLine("AppleMap Plugin", "old_map.sbMap[{1}].pdSize = {0}", old_entry.pdSize, (i - 2) / 12);
+ DicConsole.DebugWriteLine("AppleMap Plugin", "old_map.sbMap[{1}].pdFSID = 0x{0:X8}", old_entry.pdFSID, (i - 2) / 12);
+
+ if(old_entry.pdSize == 0 && old_entry.pdFSID == 0)
+ {
+ if(old_entry.pdStart == 0)
+ break;
+ continue;
+ }
+
+ CommonTypes.Partition part = new CommonTypes.Partition
+ {
+ PartitionLength = old_entry.pdStart * ddm.sbBlockSize,
+ PartitionSectors = (old_entry.pdStart * ddm.sbBlockSize) / sector_size,
+ PartitionSequence = sequence,
+ PartitionStart = old_entry.pdSize * ddm.sbBlockSize,
+ PartitionStartSector = (old_entry.pdSize * ddm.sbBlockSize) / sector_size,
+ };
+
+ if(old_entry.pdFSID == HFS_MAGIC_OLD)
+ part.PartitionType = "Apple_HFS";
+ else
+ part.PartitionType = string.Format("0x{0:X8}", old_entry.pdFSID);
+
+ partitions.Add(part);
+
+ sequence++;
+ }
+
+ return true;
+ }
+
+ AppleMapPartitionEntry entry;
+ uint entry_size;
+ uint entry_count;
+ uint sectors_to_read;
+ uint skip_ddm;
+
+ // If sector is bigger than 512
+ if(sector_size > 512)
+ {
+ byte[] tmp = new byte[512];
+ Array.Copy(ddm_sector, 512, tmp, 0, 512);
+ entry = BigEndianMarshal.ByteArrayToStructureBigEndian(tmp);
+ // Check for a partition entry that's 512-byte aligned
+ if(entry.signature == APM_MAGIC)
+ {
+ DicConsole.DebugWriteLine("AppleMap Plugin", "Found misaligned entry.");
+ entry_size = 512;
+ entry_count = entry.entries;
+ skip_ddm = 512;
+ sectors_to_read = (((entry_count + 1) * 512) / sector_size) + 1;
}
else
{
- APMEntry_sector = imagePlugin.ReadSector(first_sector);
- APMEntry = DecodeAPMEntry(APMEntry_sector);
-
- if(APMEntry.signature != APM_ENTRY && APMEntry.signature != APM_OLDENT)
- return false;
+ entry = BigEndianMarshal.ByteArrayToStructureBigEndian(part_sector);
+ if(entry.signature == APM_MAGIC)
+ {
+ DicConsole.DebugWriteLine("AppleMap Plugin", "Found aligned entry.");
+ entry_size = sector_size;
+ entry_count = entry.entries;
+ skip_ddm = sector_size;
+ sectors_to_read = entry_count + 2;
+ }
+ else
+ return true;
}
}
else
{
- APMEntry_sector = imagePlugin.ReadSector(first_sector);
- APMEntry = DecodeAPMEntry(APMEntry_sector);
-
- if(APMEntry.signature != APM_ENTRY && APMEntry.signature != APM_OLDENT)
- return false;
- }
-
- if(APMEntry.entries <= 1)
- return false;
-
- apm_entries = APMEntry.entries;
-
- for(ulong i = 0; i < apm_entries; i++) // For each partition
- {
- if(APMFromHDDOnCD)
+ entry = BigEndianMarshal.ByteArrayToStructureBigEndian(part_sector);
+ if(entry.signature == APM_MAGIC)
{
- return false;
- // TODO This needs several retesting
- // APMEntry_sector = Read2048SectorAs512(imagePlugin, first_sector + i);
+ DicConsole.DebugWriteLine("AppleMap Plugin", "Found aligned entry.");
+ entry_size = sector_size;
+ entry_count = entry.entries;
+ skip_ddm = sector_size;
+ sectors_to_read = entry_count + 2;
}
else
- APMEntry_sector = imagePlugin.ReadSector(first_sector + i);
+ return true;
+ }
- APMEntry = DecodeAPMEntry(APMEntry_sector);
+ byte[] entries = imagePlugin.ReadSectors(0, sectors_to_read);
+ DicConsole.DebugWriteLine("AppleMap Plugin", "entry_size = {0}", entry_size);
+ DicConsole.DebugWriteLine("AppleMap Plugin", "entry_count = {0}", entry_count);
+ DicConsole.DebugWriteLine("AppleMap Plugin", "skip_ddm = {0}", skip_ddm);
+ DicConsole.DebugWriteLine("AppleMap Plugin", "sectors_to_read = {0}", sectors_to_read);
- if(APMEntry.signature == APM_ENTRY || APMEntry.signature == APM_OLDENT) // It should have partition entry signature
+ byte[] copy = new byte[entries.Length - skip_ddm];
+ Array.Copy(entries, skip_ddm, copy, 0, copy.Length);
+ entries = copy;
+
+ for(int i = 0; i < entry_count; i++)
+ {
+ byte[] tmp = new byte[entry_size];
+ Array.Copy(entries, i * entry_size, tmp, 0, entry_size);
+ entry = BigEndianMarshal.ByteArrayToStructureBigEndian(tmp);
+ if(entry.signature == APM_MAGIC)
{
- CommonTypes.Partition _partition = new CommonTypes.Partition();
- StringBuilder sb = new StringBuilder();
+ DicConsole.DebugWriteLine("AppleMap Plugin", "dpme[{0}].signature = 0x{1:X4}", i, entry.signature);
+ DicConsole.DebugWriteLine("AppleMap Plugin", "dpme[{0}].reserved1 = 0x{1:X4}", i, entry.reserved1);
+ DicConsole.DebugWriteLine("AppleMap Plugin", "dpme[{0}].entries = {1}", i, entry.entries);
+ DicConsole.DebugWriteLine("AppleMap Plugin", "dpme[{0}].start = {1}", i, entry.start);
+ DicConsole.DebugWriteLine("AppleMap Plugin", "dpme[{0}].sectors = {1}", i, entry.sectors);
+ DicConsole.DebugWriteLine("AppleMap Plugin", "dpme[{0}].name = \"{1}\"", i, StringHandlers.CToString(entry.name));
+ DicConsole.DebugWriteLine("AppleMap Plugin", "dpme[{0}].type = \"{1}\"", i, StringHandlers.CToString(entry.type));
+ DicConsole.DebugWriteLine("AppleMap Plugin", "dpme[{0}].first_data_block = {1}", i, entry.first_data_block);
+ DicConsole.DebugWriteLine("AppleMap Plugin", "dpme[{0}].data_sectors = {1}", i, entry.data_sectors);
+ DicConsole.DebugWriteLine("AppleMap Plugin", "dpme[{0}].flags = {1}", i, (AppleMapFlags)entry.flags);
+ DicConsole.DebugWriteLine("AppleMap Plugin", "dpme[{0}].first_boot_block = {1}", i, entry.first_boot_block);
+ DicConsole.DebugWriteLine("AppleMap Plugin", "dpme[{0}].boot_size = {1}", i, entry.boot_size);
+ DicConsole.DebugWriteLine("AppleMap Plugin", "dpme[{0}].load_address = 0x{1:X8}", i, entry.load_address);
+ DicConsole.DebugWriteLine("AppleMap Plugin", "dpme[{0}].load_address2 = 0x{1:X8}", i, entry.load_address2);
+ DicConsole.DebugWriteLine("AppleMap Plugin", "dpme[{0}].entry_point = 0x{1:X8}", i, entry.entry_point);
+ DicConsole.DebugWriteLine("AppleMap Plugin", "dpme[{0}].entry_point2 = 0x{1:X8}", i, entry.entry_point2);
+ DicConsole.DebugWriteLine("AppleMap Plugin", "dpme[{0}].checksum = 0x{1:X8}", i, entry.checksum);
+ DicConsole.DebugWriteLine("AppleMap Plugin", "dpme[{0}].processor = \"{1}\"", i, StringHandlers.CToString(entry.processor));
- _partition.PartitionSequence = i;
- _partition.PartitionType = APMEntry.type;
- _partition.PartitionName = APMEntry.name;
- _partition.PartitionStart = APMEntry.start * sector_size;
- _partition.PartitionLength = APMEntry.sectors * sector_size;
- _partition.PartitionStartSector = APMEntry.start;
- _partition.PartitionSectors = APMEntry.sectors;
+ AppleMapFlags flags = (AppleMapFlags)entry.flags;
- sb.AppendLine("Partition flags:");
- if((APMEntry.status & 0x01) == 0x01)
- sb.AppendLine("Partition is valid.");
- if((APMEntry.status & 0x02) == 0x02)
- sb.AppendLine("Partition entry is not available.");
- if((APMEntry.status & 0x04) == 0x04)
- sb.AppendLine("Partition is mounted.");
- if((APMEntry.status & 0x08) == 0x08)
- sb.AppendLine("Partition is bootable.");
- if((APMEntry.status & 0x10) == 0x10)
- sb.AppendLine("Partition is readable.");
- if((APMEntry.status & 0x20) == 0x20)
- sb.AppendLine("Partition is writable.");
- if((APMEntry.status & 0x40) == 0x40)
- sb.AppendLine("Partition's boot code is position independent.");
-
- if((APMEntry.status & 0x08) == 0x08)
+ // BeOS doesn't mark its partitions as valid
+ //if(flags.HasFlag(AppleMapFlags.Valid) &&
+ if(StringHandlers.CToString(entry.type) != "Apple_partition_map" && entry.sectors > 0)
{
- sb.AppendFormat("First boot sector: {0}", APMEntry.first_boot_block).AppendLine();
- sb.AppendFormat("Boot is {0} bytes.", APMEntry.boot_size).AppendLine();
- sb.AppendFormat("Boot load address: 0x{0:X8}", APMEntry.load_address).AppendLine();
- sb.AppendFormat("Boot entry point: 0x{0:X8}", APMEntry.entry_point).AppendLine();
- sb.AppendFormat("Boot code checksum: 0x{0:X8}", APMEntry.checksum).AppendLine();
- sb.AppendFormat("Processor: {0}", APMEntry.processor).AppendLine();
+ StringBuilder sb = new StringBuilder();
+
+ CommonTypes.Partition _partition = new CommonTypes.Partition
+ {
+ PartitionSequence = sequence,
+ PartitionType = StringHandlers.CToString(entry.type),
+ PartitionName = StringHandlers.CToString(entry.name),
+ PartitionStart = entry.start * entry_size,
+ PartitionLength = entry.sectors * entry_size,
+ PartitionStartSector = (entry.start * entry_size) / sector_size,
+ PartitionSectors = (entry.sectors * entry_size) / sector_size
+ };
+ sb.AppendLine("Partition flags:");
+ if(flags.HasFlag(AppleMapFlags.Valid))
+ sb.AppendLine("Partition is valid.");
+ if(flags.HasFlag(AppleMapFlags.Allocated))
+ sb.AppendLine("Partition entry is allocated.");
+ if(flags.HasFlag(AppleMapFlags.InUse))
+ sb.AppendLine("Partition is in use.");
+ if(flags.HasFlag(AppleMapFlags.Bootable))
+ sb.AppendLine("Partition is bootable.");
+ if(flags.HasFlag(AppleMapFlags.Readable))
+ sb.AppendLine("Partition is readable.");
+ if(flags.HasFlag(AppleMapFlags.Writable))
+ sb.AppendLine("Partition is writable.");
+
+ if(flags.HasFlag(AppleMapFlags.Bootable))
+ {
+ sb.AppendFormat("First boot sector: {0}", (entry.first_boot_block * entry_size) / sector_size).AppendLine();
+ sb.AppendFormat("Boot is {0} bytes.", entry.boot_size).AppendLine();
+ sb.AppendFormat("Boot load address: 0x{0:X8}", entry.load_address).AppendLine();
+ sb.AppendFormat("Boot entry point: 0x{0:X8}", entry.entry_point).AppendLine();
+ sb.AppendFormat("Boot code checksum: 0x{0:X8}", entry.checksum).AppendLine();
+ sb.AppendFormat("Processor: {0}", StringHandlers.CToString(entry.processor)).AppendLine();
+
+ if(flags.HasFlag(AppleMapFlags.PicCode))
+ sb.AppendLine("Partition's boot code is position independent.");
+ }
+
+ _partition.PartitionDescription = sb.ToString();
+ partitions.Add(_partition);
}
-
- _partition.PartitionDescription = sb.ToString();
-
- if((APMEntry.status & 0x01) == 0x01)
- if(APMEntry.type != "Apple_partition_map")
- partitions.Add(_partition);
}
}
return true;
}
- static byte[] Read2048SectorAs512(ImagePlugins.ImagePlugin imagePlugin, ulong LBA)
+ [StructLayout(LayoutKind.Sequential, Pack = 1)]
+ public struct AppleDriverDescriptorMap
{
- ulong LBA2k = LBA / 4;
- int Remainder = (int)(LBA % 4);
-
- byte[] buffer = imagePlugin.ReadSector(LBA2k);
- byte[] sector = new byte[512];
-
- Array.Copy(buffer, Remainder * 512, sector, 0, 512);
-
- return sector;
+ /// Signature
+ public ushort sbSig;
+ /// Byter per sector
+ public ushort sbBlockSize;
+ /// Sectors of the disk
+ public uint sbBlocks;
+ /// Device type
+ public ushort sbDevType;
+ /// Device ID
+ public ushort sbDevId;
+ /// Reserved
+ public uint sbData;
+ /// Number of entries of the driver descriptor
+ public ushort sbDrvrCount;
+ /// Entries of the driver descriptor
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 61)]
+ public AppleDriverEntry[] sbMap;
}
- static AppleMapPartitionEntry DecodeAPMEntry(byte[] APMEntry_sector)
+ [StructLayout(LayoutKind.Sequential, Pack = 1)]
+ public struct AppleDriverEntry
{
- AppleMapPartitionEntry APMEntry = new AppleMapPartitionEntry();
- byte[] cString;
-
- APMEntry.signature = BigEndianBitConverter.ToUInt16(APMEntry_sector, 0x00);
- APMEntry.reserved1 = BigEndianBitConverter.ToUInt16(APMEntry_sector, 0x02);
- APMEntry.entries = BigEndianBitConverter.ToUInt32(APMEntry_sector, 0x04);
- APMEntry.start = BigEndianBitConverter.ToUInt32(APMEntry_sector, 0x08);
- APMEntry.sectors = BigEndianBitConverter.ToUInt32(APMEntry_sector, 0x0C);
- cString = new byte[32];
- Array.Copy(APMEntry_sector, 0x10, cString, 0, 32);
- APMEntry.name = StringHandlers.CToString(cString, Encoding.GetEncoding("macintosh"));
- cString = new byte[32];
- Array.Copy(APMEntry_sector, 0x30, cString, 0, 32);
- APMEntry.type = StringHandlers.CToString(cString, Encoding.GetEncoding("macintosh"));
- APMEntry.first_data_block = BigEndianBitConverter.ToUInt32(APMEntry_sector, 0x50);
- APMEntry.data_sectors = BigEndianBitConverter.ToUInt32(APMEntry_sector, 0x54);
- APMEntry.status = BigEndianBitConverter.ToUInt32(APMEntry_sector, 0x58);
- APMEntry.first_boot_block = BigEndianBitConverter.ToUInt32(APMEntry_sector, 0x5C);
- APMEntry.boot_size = BigEndianBitConverter.ToUInt32(APMEntry_sector, 0x60);
- APMEntry.load_address = BigEndianBitConverter.ToUInt32(APMEntry_sector, 0x64);
- APMEntry.reserved2 = BigEndianBitConverter.ToUInt32(APMEntry_sector, 0x68);
- APMEntry.entry_point = BigEndianBitConverter.ToUInt32(APMEntry_sector, 0x6C);
- APMEntry.reserved3 = BigEndianBitConverter.ToUInt32(APMEntry_sector, 0x70);
- APMEntry.checksum = BigEndianBitConverter.ToUInt32(APMEntry_sector, 0x74);
- cString = new byte[16];
- Array.Copy(APMEntry_sector, 0x78, cString, 0, 16);
- APMEntry.processor = StringHandlers.CToString(cString, Encoding.GetEncoding("macintosh"));
-
- return APMEntry;
+ /// First sector of the driver
+ public uint ddBlock;
+ /// Size in 512bytes sectors of the driver
+ public ushort ddSize;
+ /// Operating system (MacOS = 1)
+ public ushort ddType;
}
- public struct AppleMapBootEntry
+ [StructLayout(LayoutKind.Sequential, Pack = 1)]
+ public struct AppleOldDevicePartitionMap
{
- // Signature ("ER")
- public ushort signature;
- // Byter per sector
- public ushort sector_size;
- // Sectors of the disk
- public uint sectors;
- // Reserved
- public ushort reserved1;
- // Reserved
- public ushort reserved2;
- // Reserved
- public uint reserved3;
- // Number of entries of the driver descriptor
- public ushort driver_entries;
- // First sector of the driver
- public uint first_driver_blk;
- // Size in 512bytes sectors of the driver
- public ushort driver_size;
- // Operating system (MacOS = 1)
- public ushort operating_system;
+ /// Signature
+ public ushort pdSig;
+ /// Entries of the driver descriptor
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 42)]
+ public AppleMapOldPartitionEntry[] pdMap;
}
+ [StructLayout(LayoutKind.Sequential, Pack = 1)]
+ public struct AppleMapOldPartitionEntry
+ {
+ /// First sector of the partition
+ public uint pdStart;
+ /// Number of sectors of the partition
+ public uint pdSize;
+ /// Partition type
+ public uint pdFSID;
+ }
+
+ [Flags]
+ public enum AppleMapFlags : uint
+ {
+ /// Partition is valid
+ Valid = 0x01,
+ /// Partition is allocated
+ Allocated = 0x02,
+ /// Partition is in use
+ InUse = 0x04,
+ /// Partition is bootable
+ Bootable = 0x08,
+ /// Partition is readable
+ Readable = 0x10,
+ /// Partition is writable
+ Writable = 0x20,
+ /// Partition boot code is position independent
+ PicCode = 0x40,
+ /// OS specific flag
+ Specific1 = 0x80,
+ /// OS specific flag
+ Specific2 = 0x100,
+ /// Unknown, seen in the wild
+ Unknown = 0x200,
+ /// Unknown, seen in the wild
+ Unknown2 = 0x40000000,
+ /// Reserved, not seen in the wild
+ Reserved = 0xBFFFFC00,
+ }
+
+
+ [StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct AppleMapPartitionEntry
{
- // Signature ("PM" or "TS")
+ /// Signature
public ushort signature;
- // Reserved
+ /// Reserved
public ushort reserved1;
- // Number of entries on the partition map, each one sector
+ /// Number of entries on the partition map, each one sector
public uint entries;
- // First sector of the partition
+ /// First sector of the partition
public uint start;
- // Number of sectos of the partition
+ /// Number of sectos of the partition
public uint sectors;
- // Partition name, 32 bytes, null-padded
- public string name;
- // Partition type. 32 bytes, null-padded
- public string type;
- // First sector of the data area
+ /// Partition name, 32 bytes, null-padded
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
+ public byte[] name;
+ /// Partition type. 32 bytes, null-padded
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
+ public byte[] type;
+ /// First sector of the data area
public uint first_data_block;
- // Number of sectors of the data area
+ /// Number of sectors of the data area
public uint data_sectors;
- // Partition status
- public uint status;
- // First sector of the boot code
+ /// Partition flags
+ public uint flags;
+ /// First sector of the boot code
public uint first_boot_block;
- // Size in bytes of the boot code
+ /// Size in bytes of the boot code
public uint boot_size;
- // Load address of the boot code
+ /// Load address of the boot code
public uint load_address;
- // Reserved
- public uint reserved2;
- // Entry point of the boot code
+ /// Load address of the boot code
+ public uint load_address2;
+ /// Entry point of the boot code
public uint entry_point;
- // Reserved
- public uint reserved3;
- // Boot code checksum
+ /// Entry point of the boot code
+ public uint entry_point2;
+ /// Boot code checksum
public uint checksum;
- // Processor type, 16 bytes, null-padded
- public string processor;
+ /// Processor type, 16 bytes, null-padded
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
+ public byte[] processor;
+ /// Boot arguments
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
+ public uint[] boot_arguments;
}
}
}
\ No newline at end of file