Added support for RRIP extensions to ISO9660.

This commit is contained in:
2017-10-09 12:07:48 +01:00
parent bdc6eda811
commit a02ef2c4d6
3 changed files with 203 additions and 23 deletions

View File

@@ -49,6 +49,16 @@ namespace DiscImageChef.Filesystems.ISO9660
const ushort SUSP_Reference = 0x4552; // "ER"
const ushort SUSP_Selector = 0x4553; // "ES"
const ushort SUSP_Magic = 0xBEEF;
const ushort RRIP_Magic = 0x5252; // "RR"
const ushort RRIP_PosixAttributes = 0x5058; // "PX"
const ushort RRIP_PosixDevNo = 0x504E; // "PN"
const ushort RRIP_Symlink = 0x534C; // "SL"
const ushort RRIP_Name = 0x4E4D; // "NM"
const ushort RRIP_Childlink = 0x434C; // "CL"
const ushort RRIP_Parentlink = 0x504C; // "PL"
const ushort RRIP_RelocatedDir = 0x5245; // "RE"
const ushort RRIP_Timestamps = 0x5446; // "TF"
const ushort RRIP_Sparse = 0x5346; // "SF"
[Flags]
enum FileFlags : byte
@@ -155,5 +165,68 @@ namespace DiscImageChef.Filesystems.ISO9660
TypeCreatorIconBundle = 5,
HFS = 6
}
[Flags]
enum PosixMode : uint
{
OwnerRead = 0x100,
OwnerWrite = 0x80,
OwnerExecute = 0x40,
GroupRead = 0x20,
GroupWrite = 0x10,
GroupExecute = 0x8,
OtherRead = 0x4,
OtherWrite = 0x2,
OtherExecute = 0x1,
SetUID = 0x800,
SetGid = 0x400,
IsVTX = 0x200,
Socket = 0xC000,
Symlink = 0xA000,
Regular = 0x8000,
Block = 0x6000,
Character = 0x2000,
Directory = 0x4000,
Pipe = 0x1000
}
[Flags]
enum SymlinkFlags : byte
{
Continue = 1
}
[Flags]
enum SymlinkComponentFlags : byte
{
Continue = 1,
Current = 2,
Parent = 4,
Root = 8,
Mountpoint = 16,
Networkname = 32
}
[Flags]
enum AlternateNameFlags : byte
{
Continue = 1,
Current = 2,
Parent = 4,
Networkname = 32
}
[Flags]
enum TimestampFlags : byte
{
Creation = 1 << 0,
Modification = 1 << 1,
Access = 1 << 2,
AttributeChange = 1 << 3,
Backup = 1 << 4,
Expiration = 1 << 5,
Effective = 1 << 6,
LongFormat = 1 << 7,
}
}
}

View File

@@ -80,7 +80,6 @@ namespace DiscImageChef.Filesystems.ISO9660
{
information = "";
StringBuilder ISOMetadata = new StringBuilder();
bool RockRidge = false;
byte VDType; // Volume Descriptor Type, should be 1 or 2.
byte[] VDMagic = new byte[5]; // Volume Descriptor magic "CD001"
byte[] HSMagic = new byte[5]; // Volume Descriptor magic "CDROM"
@@ -257,6 +256,7 @@ namespace DiscImageChef.Filesystems.ISO9660
bool XA = false;
bool Apple = false;
bool SUSP = false;
bool RRIP = false;
List<ContinuationArea> contareas = new List<ContinuationArea>();
List<byte[]> refareas = new List<byte[]>();
StringBuilder suspInformation = new StringBuilder();
@@ -370,6 +370,12 @@ namespace DiscImageChef.Filesystems.ISO9660
refareas.Add(er);
}
RRIP |= nextSignature == RRIP_Magic || nextSignature == RRIP_PosixAttributes ||
nextSignature == RRIP_PosixDevNo || nextSignature == RRIP_Symlink ||
nextSignature == RRIP_Name || nextSignature == RRIP_Childlink ||
nextSignature == RRIP_Parentlink || nextSignature == RRIP_RelocatedDir ||
nextSignature == RRIP_Timestamps || nextSignature == RRIP_Sparse;
sa_off += sa[sa_off + 2];
if(nextSignature == SUSP_Terminator)
@@ -419,6 +425,12 @@ namespace DiscImageChef.Filesystems.ISO9660
refareas.Add(er);
}
RRIP |= nextSignature == RRIP_Magic || nextSignature == RRIP_PosixAttributes ||
nextSignature == RRIP_PosixDevNo || nextSignature == RRIP_Symlink ||
nextSignature == RRIP_Name || nextSignature == RRIP_Childlink ||
nextSignature == RRIP_Parentlink || nextSignature == RRIP_RelocatedDir ||
nextSignature == RRIP_Timestamps || nextSignature == RRIP_Sparse;
ca_off += ca_data[ca_off + 2];
}
}
@@ -444,27 +456,6 @@ namespace DiscImageChef.Filesystems.ISO9660
}
}
// TODO: Check this
/*
if((i + partition.Start) < partition.End)
{
byte[] path_table = imagePlugin.ReadSector(i + partition.Start);
Array.Copy(path_table, 2, RootDirectoryLocation, 0, 4);
// Check for Rock Ridge
byte[] root_dir = imagePlugin.ReadSector((ulong)BitConverter.ToInt32(RootDirectoryLocation, 0) + partition.Start);
byte[] SUSPMagic = new byte[2];
byte[] RRMagic = new byte[2];
Array.Copy(root_dir, 0x22, SUSPMagic, 0, 2);
if(CurrentEncoding.GetString(SUSPMagic) == "SP")
{
Array.Copy(root_dir, 0x29, RRMagic, 0, 2);
RockRidge |= CurrentEncoding.GetString(RRMagic) == "RR";
}
}*/
byte[] ipbin_sector = imagePlugin.ReadSector(0 + partition.Start);
Decoders.Sega.CD.IPBin? SegaCD = Decoders.Sega.CD.DecodeIPBin(ipbin_sector);
Decoders.Sega.Saturn.IPBin? Saturn = Decoders.Sega.Saturn.DecodeIPBin(ipbin_sector);
@@ -479,7 +470,7 @@ namespace DiscImageChef.Filesystems.ISO9660
ISOMetadata.AppendLine("Joliet extensions present.");
if(SUSP)
ISOMetadata.AppendLine("System Use Sharing Protocol present.");
if(RockRidge)
if(RRIP)
ISOMetadata.AppendLine("Rock Ridge Interchange Protocol present.");
if(bvd != null)
ISOMetadata.AppendFormat("Disc bootable following {0} specifications.", BootSpec).AppendLine();

View File

@@ -493,6 +493,122 @@ namespace DiscImageChef.Filesystems.ISO9660
public byte sequence;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct PosixAttributes
{
public ushort signature;
public byte length;
public byte version;
public PosixMode st_mode;
public PosixMode st_mode_be;
public uint st_nlink;
public uint st_nlink_be;
public uint st_uid;
public uint st_uid_be;
public uint st_gid;
public uint st_gid_be;
public uint st_ino;
public uint st_ino_be;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct PosixDeviceNumber
{
public ushort signature;
public byte length;
public byte version;
public uint dev_t_high;
public uint dev_t_high_be;
public uint dev_t_low;
public uint dev_t_low_be;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct SymbolicLink
{
public ushort signature;
public byte length;
public byte version;
public SymlinkFlags flags;
// Followed by SymbolicLinkComponent (link to /bar/foo uses at least two of these structs)
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct SymbolicLinkComponent
{
public SymlinkComponentFlags flags;
public byte length;
// Followed by component content
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct AlternateName
{
public ushort signature;
public byte length;
public byte version;
public AlternateNameFlags flags;
// Folowed by name, can be divided in pieces
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct ChildLink
{
public ushort signature;
public byte length;
public byte version;
public uint child_dir_lba;
public uint child_dir_lba_be;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct ParentLink
{
public ushort signature;
public byte length;
public byte version;
public uint parent_dir_lba;
public uint parent_dir_lba_be;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct RelocatedDirectory
{
public ushort signature;
public byte length;
public byte version;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct Timestamps
{
public ushort signature;
public byte length;
public byte version;
public TimestampFlags flags;
// If flags indicate long format, timestamps are 17 bytes, if not, 7 bytes
// Followed by creation time if present
// Followed by modification time if present
// Followed by access time if present
// Followed by attribute change time if present
// Followed by backup time if present
// Followed by expiration time if present
// Followed by effective time if present
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct SparseFile
{
public ushort signature;
public byte length;
public byte version;
public uint virtual_size_high;
public uint virtual_size_high_be;
public uint virtual_size_low;
public uint virtual_size_low_be;
public byte table_depth;
}
struct DecodedVolumeDescriptor
{
public string SystemIdentifier;