Added support for Apple Extensions to ISO 9660.

This commit is contained in:
2017-10-09 09:48:28 +01:00
parent 1698f3264a
commit be104ae04a
3 changed files with 142 additions and 5 deletions

View File

@@ -40,6 +40,8 @@ namespace DiscImageChef.Filesystems.ISO9660
const ushort ElToritoMagic = 0xAA55; const ushort ElToritoMagic = 0xAA55;
const int ElToritoEntrySize = 32; const int ElToritoEntrySize = 32;
const ushort XaMagic = 0x5841; // "XA" const ushort XaMagic = 0x5841; // "XA"
const ushort AppleMagic = 0x4141; // "AA"
const ushort AppleMagicOld = 0x4241; // "BA"
[Flags] [Flags]
enum FileFlags : byte enum FileFlags : byte
@@ -130,5 +132,21 @@ namespace DiscImageChef.Filesystems.ISO9660
ATAPI = 0x40, ATAPI = 0x40,
SCSI = 0x08 SCSI = 0x08
} }
enum AppleId : byte
{
ProDOS = 1,
HFS = 2
}
enum AppleOldId : byte
{
ProDOS = 1,
TypeCreator = 2,
TypeCreatorBundle = 3,
TypeCreatorIcon = 4,
TypeCreatorIconBundle = 5,
HFS = 6
}
} }
} }

View File

@@ -254,6 +254,9 @@ namespace DiscImageChef.Filesystems.ISO9660
byte[] root_dir = imagePlugin.ReadSectors(rootLocation + partition.Start, rootSize); byte[] root_dir = imagePlugin.ReadSectors(rootLocation + partition.Start, rootSize);
int rootOff = 0; int rootOff = 0;
bool XA = false; bool XA = false;
bool Apple = false;
BigEndianBitConverter.IsLittleEndian = BitConverter.IsLittleEndian;
// Walk thru root directory to see system area extensions in use // Walk thru root directory to see system area extensions in use
while(rootOff + Marshal.SizeOf(typeof(DirectoryRecord)) < root_dir.Length) while(rootOff + Marshal.SizeOf(typeof(DirectoryRecord)) < root_dir.Length)
@@ -274,6 +277,10 @@ namespace DiscImageChef.Filesystems.ISO9660
Array.Copy(root_dir, rootOff + sa_off, sa, 0, sa_len); Array.Copy(root_dir, rootOff + sa_off, sa, 0, sa_len);
sa_off = 0; sa_off = 0;
while(sa_off < sa_len)
{
bool noneFound = true;
if(Marshal.SizeOf(typeof(CdromXa)) + sa_off <= sa_len) if(Marshal.SizeOf(typeof(CdromXa)) + sa_off <= sa_len)
{ {
CdromXa xa = BigEndianMarshal.ByteArrayToStructureBigEndian<CdromXa>(sa); CdromXa xa = BigEndianMarshal.ByteArrayToStructureBigEndian<CdromXa>(sa);
@@ -281,8 +288,52 @@ namespace DiscImageChef.Filesystems.ISO9660
{ {
XA = true; XA = true;
sa_off += Marshal.SizeOf(typeof(CdromXa)); sa_off += Marshal.SizeOf(typeof(CdromXa));
noneFound = false;
} }
} }
if(sa_off >= sa_len)
break;
ushort nextSignature = BigEndianBitConverter.ToUInt16(sa, sa_off);
// Easy, contains size field
if(nextSignature == AppleMagic)
{
Apple = true;
sa_off += sa[sa_off + 2];
noneFound = false;
}
// Not easy, contains size field
if(nextSignature == AppleMagicOld)
{
Apple = true;
AppleOldId apple_id = (AppleOldId)sa[sa_off + 2];
noneFound = false;
switch(apple_id)
{
case AppleOldId.ProDOS:
sa_off += Marshal.SizeOf(typeof(AppleProDOSOldSystemUse));
break;
case AppleOldId.TypeCreator:
case AppleOldId.TypeCreatorBundle:
sa_off += Marshal.SizeOf(typeof(AppleHFSTypeCreatorSystemUse));
break;
case AppleOldId.TypeCreatorIcon:
case AppleOldId.TypeCreatorIconBundle:
sa_off += Marshal.SizeOf(typeof(AppleHFSIconSystemUse));
break;
case AppleOldId.HFS:
sa_off += Marshal.SizeOf(typeof(AppleHFSOldSystemUse));
break;
}
}
if(noneFound)
break;
}
} }
rootOff += record.length; rootOff += record.length;
@@ -321,6 +372,8 @@ namespace DiscImageChef.Filesystems.ISO9660
ISOMetadata.AppendFormat("{0} file system", HighSierra ? "High Sierra Format" : "ISO9660").AppendLine(); ISOMetadata.AppendFormat("{0} file system", HighSierra ? "High Sierra Format" : "ISO9660").AppendLine();
if(XA) if(XA)
ISOMetadata.AppendLine("CD-ROM XA extensions present."); ISOMetadata.AppendLine("CD-ROM XA extensions present.");
if(Apple)
ISOMetadata.AppendLine("Apple extensions present.");
if(jolietvd != null) if(jolietvd != null)
ISOMetadata.AppendLine("Joliet extensions present."); ISOMetadata.AppendLine("Joliet extensions present.");
if(RockRidge) if(RockRidge)

View File

@@ -363,6 +363,72 @@ namespace DiscImageChef.Filesystems.ISO9660
public byte[] reserved; public byte[] reserved;
} }
// Little-endian
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct AppleProDOSSystemUse
{
public ushort signature;
public byte length;
public AppleId id;
public byte type;
public ushort aux_type;
}
// Big-endian
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct AppleHFSSystemUse
{
public ushort signature;
public byte length;
public AppleId id;
public ushort type;
public ushort creator;
public ushort finder_flags;
}
// Little-endian
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct AppleProDOSOldSystemUse
{
public ushort signature;
public AppleOldId id;
public byte type;
public ushort aux_type;
}
// Big-endian
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct AppleHFSTypeCreatorSystemUse
{
public ushort signature;
public AppleOldId id;
public ushort type;
public ushort creator;
}
// Big-endian
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct AppleHFSIconSystemUse
{
public ushort signature;
public AppleOldId id;
public ushort type;
public ushort creator;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public byte[] icon;
}
// Big-endian
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct AppleHFSOldSystemUse
{
public ushort signature;
public AppleOldId id;
public ushort type;
public ushort creator;
public ushort finder_flags;
}
struct DecodedVolumeDescriptor struct DecodedVolumeDescriptor
{ {
public string SystemIdentifier; public string SystemIdentifier;