From be104ae04a8ab9f79e4c457445f6b4c2acd9a821 Mon Sep 17 00:00:00 2001 From: Natalia Portillo Date: Mon, 9 Oct 2017 09:48:28 +0100 Subject: [PATCH] Added support for Apple Extensions to ISO 9660. --- DiscImageChef.Filesystems/ISO9660/Consts.cs | 18 ++++++ DiscImageChef.Filesystems/ISO9660/Info.cs | 63 +++++++++++++++++-- DiscImageChef.Filesystems/ISO9660/Structs.cs | 66 ++++++++++++++++++++ 3 files changed, 142 insertions(+), 5 deletions(-) diff --git a/DiscImageChef.Filesystems/ISO9660/Consts.cs b/DiscImageChef.Filesystems/ISO9660/Consts.cs index 4a977d48..31708b1b 100644 --- a/DiscImageChef.Filesystems/ISO9660/Consts.cs +++ b/DiscImageChef.Filesystems/ISO9660/Consts.cs @@ -40,6 +40,8 @@ namespace DiscImageChef.Filesystems.ISO9660 const ushort ElToritoMagic = 0xAA55; const int ElToritoEntrySize = 32; const ushort XaMagic = 0x5841; // "XA" + const ushort AppleMagic = 0x4141; // "AA" + const ushort AppleMagicOld = 0x4241; // "BA" [Flags] enum FileFlags : byte @@ -130,5 +132,21 @@ namespace DiscImageChef.Filesystems.ISO9660 ATAPI = 0x40, SCSI = 0x08 } + + enum AppleId : byte + { + ProDOS = 1, + HFS = 2 + } + + enum AppleOldId : byte + { + ProDOS = 1, + TypeCreator = 2, + TypeCreatorBundle = 3, + TypeCreatorIcon = 4, + TypeCreatorIconBundle = 5, + HFS = 6 + } } } diff --git a/DiscImageChef.Filesystems/ISO9660/Info.cs b/DiscImageChef.Filesystems/ISO9660/Info.cs index 8e2adafd..0e6f8117 100644 --- a/DiscImageChef.Filesystems/ISO9660/Info.cs +++ b/DiscImageChef.Filesystems/ISO9660/Info.cs @@ -254,6 +254,9 @@ namespace DiscImageChef.Filesystems.ISO9660 byte[] root_dir = imagePlugin.ReadSectors(rootLocation + partition.Start, rootSize); int rootOff = 0; bool XA = false; + bool Apple = false; + + BigEndianBitConverter.IsLittleEndian = BitConverter.IsLittleEndian; // Walk thru root directory to see system area extensions in use while(rootOff + Marshal.SizeOf(typeof(DirectoryRecord)) < root_dir.Length) @@ -274,14 +277,62 @@ namespace DiscImageChef.Filesystems.ISO9660 Array.Copy(root_dir, rootOff + sa_off, sa, 0, sa_len); sa_off = 0; - if(Marshal.SizeOf(typeof(CdromXa)) + sa_off <= sa_len) + while(sa_off < sa_len) { - CdromXa xa = BigEndianMarshal.ByteArrayToStructureBigEndian(sa); - if(xa.signature == XaMagic) + bool noneFound = true; + + if(Marshal.SizeOf(typeof(CdromXa)) + sa_off <= sa_len) { - XA = true; - sa_off += Marshal.SizeOf(typeof(CdromXa)); + CdromXa xa = BigEndianMarshal.ByteArrayToStructureBigEndian(sa); + if(xa.signature == XaMagic) + { + XA = true; + 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; } } @@ -321,6 +372,8 @@ namespace DiscImageChef.Filesystems.ISO9660 ISOMetadata.AppendFormat("{0} file system", HighSierra ? "High Sierra Format" : "ISO9660").AppendLine(); if(XA) ISOMetadata.AppendLine("CD-ROM XA extensions present."); + if(Apple) + ISOMetadata.AppendLine("Apple extensions present."); if(jolietvd != null) ISOMetadata.AppendLine("Joliet extensions present."); if(RockRidge) diff --git a/DiscImageChef.Filesystems/ISO9660/Structs.cs b/DiscImageChef.Filesystems/ISO9660/Structs.cs index 213535aa..08f10426 100644 --- a/DiscImageChef.Filesystems/ISO9660/Structs.cs +++ b/DiscImageChef.Filesystems/ISO9660/Structs.cs @@ -363,6 +363,72 @@ namespace DiscImageChef.Filesystems.ISO9660 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 { public string SystemIdentifier;