2016-07-28 18:13:49 +01:00
// /***************************************************************************
// The Disc Image Chef
// ----------------------------------------------------------------------------
//
// Filename : AppleMap.cs
// Author(s) : Natalia Portillo <claunia@claunia.com>
//
// Component : Partitioning scheme plugins.
//
// --[ Description ] ----------------------------------------------------------
//
// Manages Apple Partition Map.
//
// --[ 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 <http://www.gnu.org/licenses/>.
//
// ----------------------------------------------------------------------------
2017-05-19 20:28:49 +01:00
// Copyright © 2011-2017 Natalia Portillo
2016-07-28 18:13:49 +01:00
// ****************************************************************************/
2014-04-17 19:58:14 +00:00
2011-03-03 18:34:33 +00:00
using System ;
using System.Text ;
using System.Collections.Generic ;
2015-10-18 22:04:03 +01:00
using DiscImageChef.Console ;
2017-07-13 00:19:21 +01:00
using System.Runtime.InteropServices ;
2015-10-18 22:04:03 +01:00
2014-06-15 23:39:34 +01:00
namespace DiscImageChef.PartPlugins
2011-03-03 18:34:33 +00:00
{
2016-07-28 22:25:26 +01:00
// Information about structures learnt from Inside Macintosh
// Constants from image testing
2017-07-01 20:54:02 +01:00
public class AppleMap : PartPlugin
2014-04-14 02:29:13 +00:00
{
2017-07-13 00:19:21 +01:00
/// <summary>"ER", driver descriptor magic</summary>
const ushort DDM_MAGIC = 0x4552 ;
/// <summary>"PM", new entry magic</summary>
const ushort APM_MAGIC = 0x504D ;
/// <summary>"TS", old map magic</summary>
const ushort APM_MAGIC_OLD = 0x5453 ;
/// <summary>Old indicator for HFS partition, "TFS1"</summary>
const uint HFS_MAGIC_OLD = 0x54465331 ;
2012-08-05 03:02:55 +00:00
2015-10-05 19:58:42 +01:00
public AppleMap ( )
2014-04-14 02:29:13 +00:00
{
2014-04-14 01:14:20 +00:00
Name = "Apple Partition Map" ;
2014-04-14 02:29:13 +00:00
PluginUUID = new Guid ( "36405F8D-4F1A-07F5-209C-223D735D6D22" ) ;
}
2015-10-05 19:45:07 +01:00
public override bool GetInformation ( ImagePlugins . ImagePlugin imagePlugin , out List < CommonTypes . Partition > partitions )
2014-04-14 02:29:13 +00:00
{
2014-04-14 01:14:20 +00:00
uint sector_size ;
2016-04-19 02:11:47 +01:00
if ( imagePlugin . GetSectorSize ( ) = = 2352 | | imagePlugin . GetSectorSize ( ) = = 2448 )
2014-04-14 01:14:20 +00:00
sector_size = 2048 ;
else
sector_size = imagePlugin . GetSectorSize ( ) ;
2016-04-19 02:11:47 +01:00
2015-10-05 19:45:07 +01:00
partitions = new List < CommonTypes . Partition > ( ) ;
2016-04-19 02:11:47 +01:00
2017-07-13 00:19:21 +01:00
byte [ ] ddm_sector = imagePlugin . ReadSector ( 0 ) ;
AppleDriverDescriptorMap ddm ;
ushort max_drivers = 61 ;
if ( sector_size = = 256 )
2014-08-28 18:26:14 +01:00
{
2017-07-13 00:19:21 +01:00
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 < AppleDriverDescriptorMap > ( ddm_sector ) ;
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 ) ;
uint sequence = 0 ;
2017-07-15 01:36:13 +01:00
if ( ddm . sbSig = = DDM_MAGIC )
2017-07-13 00:19:21 +01:00
{
2017-07-15 01:36:13 +01:00
if ( ddm . sbDrvrCount < max_drivers )
2014-08-28 18:26:14 +01:00
{
2017-07-15 01:36:13 +01:00
ddm . sbMap = new AppleDriverEntry [ ddm . sbDrvrCount ] ;
for ( int i = 0 ; i < ddm . sbDrvrCount ; i + + )
2017-07-13 00:19:21 +01:00
{
2017-07-15 01:36:13 +01:00
byte [ ] tmp = new byte [ 8 ] ;
Array . Copy ( ddm_sector , 18 + i * 8 , tmp , 0 , 8 ) ;
ddm . sbMap [ i ] = BigEndianMarshal . ByteArrayToStructureBigEndian < AppleDriverEntry > ( 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 ) ;
2017-07-20 13:12:36 +01:00
if ( ddm . sbMap [ i ] . ddSize = = 0 )
continue ;
2017-07-15 01:36:13 +01:00
CommonTypes . Partition part = new CommonTypes . Partition ( )
{
2017-07-19 16:37:11 +01:00
Size = ( ulong ) ( ddm . sbMap [ i ] . ddSize * 512 ) ,
Length = ( ulong ) ( ( ddm . sbMap [ i ] . ddSize * 512 ) / sector_size ) ,
Sequence = sequence ,
Offset = ddm . sbMap [ i ] . ddBlock * sector_size ,
Start = ddm . sbMap [ i ] . ddBlock ,
Type = "Apple_Driver"
2017-07-15 01:36:13 +01:00
} ;
2017-07-13 00:19:21 +01:00
2017-07-20 13:12:36 +01:00
if ( ( ddm . sbMap [ i ] . ddSize * 512 ) % sector_size > 0 )
part . Length + + ;
2017-07-15 01:36:13 +01:00
partitions . Add ( part ) ;
2014-08-28 18:26:14 +01:00
2017-07-15 01:36:13 +01:00
sequence + + ;
}
2014-08-28 18:26:14 +01:00
}
}
2017-07-13 00:19:21 +01:00
byte [ ] part_sector = imagePlugin . ReadSector ( 1 ) ;
AppleOldDevicePartitionMap old_map = BigEndianMarshal . ByteArrayToStructureBigEndian < AppleOldDevicePartitionMap > ( part_sector ) ;
// This is the easy one, no sector size mixing
if ( old_map . pdSig = = APM_MAGIC_OLD )
2014-08-28 18:26:14 +01:00
{
2017-07-13 00:19:21 +01:00
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 < AppleMapOldPartitionEntry > ( 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 ;
}
2014-08-28 18:26:14 +01:00
2017-07-13 00:19:21 +01:00
CommonTypes . Partition part = new CommonTypes . Partition
{
2017-07-19 16:37:11 +01:00
Size = old_entry . pdStart * ddm . sbBlockSize ,
Length = ( old_entry . pdStart * ddm . sbBlockSize ) / sector_size ,
Sequence = sequence ,
Offset = old_entry . pdSize * ddm . sbBlockSize ,
Start = ( old_entry . pdSize * ddm . sbBlockSize ) / sector_size ,
2017-07-13 00:19:21 +01:00
} ;
2014-04-14 01:14:20 +00:00
2017-07-13 00:19:21 +01:00
if ( old_entry . pdFSID = = HFS_MAGIC_OLD )
2017-07-19 16:37:11 +01:00
part . Type = "Apple_HFS" ;
2017-07-13 00:19:21 +01:00
else
2017-07-19 16:37:11 +01:00
part . Type = string . Format ( "0x{0:X8}" , old_entry . pdFSID ) ;
2017-07-13 00:19:21 +01:00
partitions . Add ( part ) ;
2014-04-14 01:14:20 +00:00
2017-07-13 00:19:21 +01:00
sequence + + ;
}
2017-07-15 01:36:13 +01:00
return partitions . Count > 0 ;
2017-07-13 00:19:21 +01:00
}
2016-04-19 02:11:47 +01:00
2017-07-13 00:19:21 +01:00
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 )
2014-04-14 02:29:13 +00:00
{
2017-07-13 00:19:21 +01:00
byte [ ] tmp = new byte [ 512 ] ;
Array . Copy ( ddm_sector , 512 , tmp , 0 , 512 ) ;
entry = BigEndianMarshal . ByteArrayToStructureBigEndian < AppleMapPartitionEntry > ( tmp ) ;
// Check for a partition entry that's 512-byte aligned
if ( entry . signature = = APM_MAGIC )
2016-08-09 15:31:44 +01:00
{
2017-07-13 00:19:21 +01:00
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 ;
2016-08-09 15:31:44 +01:00
}
2014-08-28 18:26:14 +01:00
else
2014-04-14 02:29:13 +00:00
{
2017-07-13 00:19:21 +01:00
entry = BigEndianMarshal . ByteArrayToStructureBigEndian < AppleMapPartitionEntry > ( part_sector ) ;
if ( entry . signature = = APM_MAGIC )
2014-04-14 02:29:13 +00:00
{
2017-07-13 00:19:21 +01:00
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 ;
2014-04-14 02:29:13 +00:00
}
2017-07-13 00:19:21 +01:00
else
2017-07-15 01:36:13 +01:00
return partitions . Count > 0 ;
2017-07-13 00:19:21 +01:00
}
}
else
{
entry = BigEndianMarshal . ByteArrayToStructureBigEndian < AppleMapPartitionEntry > ( 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
2017-07-15 01:36:13 +01:00
return partitions . Count > 0 ;
2017-07-13 00:19:21 +01:00
}
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 ) ;
2016-04-19 02:11:47 +01:00
2017-07-13 00:19:21 +01:00
byte [ ] copy = new byte [ entries . Length - skip_ddm ] ;
Array . Copy ( entries , skip_ddm , copy , 0 , copy . Length ) ;
entries = copy ;
2016-04-19 02:11:47 +01:00
2017-07-13 00:19:21 +01:00
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 < AppleMapPartitionEntry > ( tmp ) ;
if ( entry . signature = = APM_MAGIC )
{
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 ) ) ;
AppleMapFlags flags = ( AppleMapFlags ) entry . flags ;
// BeOS doesn't mark its partitions as valid
//if(flags.HasFlag(AppleMapFlags.Valid) &&
2017-07-23 19:57:10 +01:00
if ( StringHandlers . CToString ( entry . type ) ! = "Apple_partition_map" & & entry . sectors > 0 )
2017-07-13 00:19:21 +01:00
{
StringBuilder sb = new StringBuilder ( ) ;
CommonTypes . Partition _partition = new CommonTypes . Partition
{
2017-07-19 16:37:11 +01:00
Sequence = sequence ,
Type = StringHandlers . CToString ( entry . type ) ,
Name = StringHandlers . CToString ( entry . name ) ,
Offset = entry . start * entry_size ,
Size = entry . sectors * entry_size ,
Start = ( entry . start * entry_size ) / sector_size ,
Length = ( entry . sectors * entry_size ) / sector_size
2017-07-13 00:19:21 +01:00
} ;
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." ) ;
}
2017-07-19 16:37:11 +01:00
_partition . Description = sb . ToString ( ) ;
2017-07-23 19:57:10 +01:00
// Some CD and DVDs end with an Apple_Free that expands beyond the disc size...
if ( _partition . End < imagePlugin . ImageInfo . sectors )
{
partitions . Add ( _partition ) ;
sequence + + ;
}
else
{
DicConsole . DebugWriteLine ( "AppleMap Plugin" , "Not adding partition because end ({0}) is outside media size ({1})" , _partition . End , imagePlugin . ImageInfo . sectors ) ;
}
2017-07-13 00:19:21 +01:00
}
2014-04-14 02:29:13 +00:00
}
}
2016-04-19 02:11:47 +01:00
2017-07-15 01:36:13 +01:00
return partitions . Count > 0 ;
2014-04-14 02:29:13 +00:00
}
2017-07-13 00:19:21 +01:00
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct AppleDriverDescriptorMap
2014-08-28 18:26:14 +01:00
{
2017-07-13 00:19:21 +01:00
/// <summary>Signature <see cref="DDM_MAGIC"/></summary>
public ushort sbSig ;
/// <summary>Byter per sector</summary>
public ushort sbBlockSize ;
/// <summary>Sectors of the disk</summary>
public uint sbBlocks ;
/// <summary>Device type</summary>
public ushort sbDevType ;
/// <summary>Device ID</summary>
public ushort sbDevId ;
/// <summary>Reserved</summary>
public uint sbData ;
/// <summary>Number of entries of the driver descriptor</summary>
public ushort sbDrvrCount ;
/// <summary>Entries of the driver descriptor</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 61)]
public AppleDriverEntry [ ] sbMap ;
}
2014-08-28 18:26:14 +01:00
2017-07-13 00:19:21 +01:00
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct AppleDriverEntry
{
/// <summary>First sector of the driver</summary>
public uint ddBlock ;
/// <summary>Size in 512bytes sectors of the driver</summary>
public ushort ddSize ;
/// <summary>Operating system (MacOS = 1)</summary>
public ushort ddType ;
}
2014-08-28 18:26:14 +01:00
2017-07-13 00:19:21 +01:00
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct AppleOldDevicePartitionMap
{
/// <summary>Signature <see cref="APM_MAGIC_OLD"/></summary>
public ushort pdSig ;
/// <summary>Entries of the driver descriptor</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 42)]
public AppleMapOldPartitionEntry [ ] pdMap ;
2014-08-28 18:26:14 +01:00
}
2017-07-13 00:19:21 +01:00
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct AppleMapOldPartitionEntry
2014-08-28 18:26:14 +01:00
{
2017-07-13 00:19:21 +01:00
/// <summary>First sector of the partition</summary>
public uint pdStart ;
/// <summary>Number of sectors of the partition</summary>
public uint pdSize ;
/// <summary>Partition type</summary>
public uint pdFSID ;
2014-08-28 18:26:14 +01:00
}
2017-07-13 00:19:21 +01:00
[Flags]
public enum AppleMapFlags : uint
2014-04-14 02:29:13 +00:00
{
2017-07-13 00:19:21 +01:00
/// <summary>Partition is valid</summary>
Valid = 0x01 ,
/// <summary>Partition is allocated</summary>
Allocated = 0x02 ,
/// <summary>Partition is in use</summary>
InUse = 0x04 ,
/// <summary>Partition is bootable</summary>
Bootable = 0x08 ,
/// <summary>Partition is readable</summary>
Readable = 0x10 ,
/// <summary>Partition is writable</summary>
Writable = 0x20 ,
/// <summary>Partition boot code is position independent</summary>
PicCode = 0x40 ,
/// <summary>OS specific flag</summary>
Specific1 = 0x80 ,
/// <summary>OS specific flag</summary>
Specific2 = 0x100 ,
/// <summary>Unknown, seen in the wild</summary>
Unknown = 0x200 ,
/// <summary>Unknown, seen in the wild</summary>
Unknown2 = 0x40000000 ,
/// <summary>Reserved, not seen in the wild</summary>
Reserved = 0xBFFFFC00 ,
2014-04-14 02:29:13 +00:00
}
2017-07-13 00:19:21 +01:00
[StructLayout(LayoutKind.Sequential, Pack = 1)]
2014-04-14 02:29:13 +00:00
public struct AppleMapPartitionEntry
{
2017-07-13 00:19:21 +01:00
/// <summary>Signature <see cref="APM_MAGIC"/></summary>
2016-07-28 22:25:26 +01:00
public ushort signature ;
2017-07-13 00:19:21 +01:00
/// <summary>Reserved</summary>
2016-07-28 22:25:26 +01:00
public ushort reserved1 ;
2017-07-13 00:19:21 +01:00
/// <summary>Number of entries on the partition map, each one sector</summary>
2016-07-28 22:25:26 +01:00
public uint entries ;
2017-07-13 00:19:21 +01:00
/// <summary>First sector of the partition</summary>
2016-07-28 22:25:26 +01:00
public uint start ;
2017-07-13 00:19:21 +01:00
/// <summary>Number of sectos of the partition</summary>
2016-07-28 22:25:26 +01:00
public uint sectors ;
2017-07-13 00:19:21 +01:00
/// <summary>Partition name, 32 bytes, null-padded</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public byte [ ] name ;
/// <summary>Partition type. 32 bytes, null-padded</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public byte [ ] type ;
/// <summary>First sector of the data area</summary>
2016-07-28 22:25:26 +01:00
public uint first_data_block ;
2017-07-13 00:19:21 +01:00
/// <summary>Number of sectors of the data area</summary>
2016-07-28 22:25:26 +01:00
public uint data_sectors ;
2017-07-13 00:19:21 +01:00
/// <summary>Partition flags</summary>
public uint flags ;
/// <summary>First sector of the boot code</summary>
2016-07-28 22:25:26 +01:00
public uint first_boot_block ;
2017-07-13 00:19:21 +01:00
/// <summary>Size in bytes of the boot code</summary>
2016-07-28 22:25:26 +01:00
public uint boot_size ;
2017-07-13 00:19:21 +01:00
/// <summary>Load address of the boot code</summary>
2016-07-28 22:25:26 +01:00
public uint load_address ;
2017-07-13 00:19:21 +01:00
/// <summary>Load address of the boot code</summary>
public uint load_address2 ;
/// <summary>Entry point of the boot code</summary>
2016-07-28 22:25:26 +01:00
public uint entry_point ;
2017-07-13 00:19:21 +01:00
/// <summary>Entry point of the boot code</summary>
public uint entry_point2 ;
/// <summary>Boot code checksum</summary>
2016-07-28 22:25:26 +01:00
public uint checksum ;
2017-07-13 00:19:21 +01:00
/// <summary>Processor type, 16 bytes, null-padded</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte [ ] processor ;
/// <summary>Boot arguments</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public uint [ ] boot_arguments ;
2014-04-14 02:29:13 +00:00
}
}
2011-03-03 18:34:33 +00:00
}