Decode XA system area.

This commit is contained in:
2019-07-28 16:48:18 +01:00
parent 7711685439
commit a6c2da7689
4 changed files with 144 additions and 82 deletions

View File

@@ -200,99 +200,146 @@ namespace DiscImageChef.Filesystems.ISO9660
bool hasResourceFork = false; bool hasResourceFork = false;
if(systemAreaLength > 2) int systemAreaOff = systemAreaStart;
int systemAreaEnd = systemAreaStart + systemAreaLength;
while(systemAreaOff + 2 <= systemAreaEnd)
{ {
ushort systemAreaSignature = BigEndianBitConverter.ToUInt16(data, systemAreaStart); ushort systemAreaSignature = BigEndianBitConverter.ToUInt16(data, systemAreaOff);
if(systemAreaSignature == APPLE_MAGIC) if(BigEndianBitConverter.ToUInt16(data, systemAreaOff + 6) == XA_MAGIC)
systemAreaSignature = XA_MAGIC;
switch(systemAreaSignature)
{ {
AppleId appleId = (AppleId)data[systemAreaStart + 3]; case APPLE_MAGIC:
byte appleLength = data[systemAreaOff + 2];
AppleId appleId = (AppleId)data[systemAreaOff + 3];
switch(appleId) switch(appleId)
{ {
case AppleId.ProDOS: case AppleId.ProDOS:
AppleProDOSSystemUse appleProDosSystemUse = AppleProDOSSystemUse appleProDosSystemUse =
Marshal.ByteArrayToStructureLittleEndian<AppleProDOSSystemUse>(data, Marshal.ByteArrayToStructureLittleEndian<AppleProDOSSystemUse>(data,
systemAreaStart, systemAreaOff,
systemAreaLength); Marshal
.SizeOf<
AppleProDOSSystemUse
>());
entry.AppleProDosType = appleProDosSystemUse.aux_type; entry.AppleProDosType = appleProDosSystemUse.aux_type;
entry.AppleDosType = appleProDosSystemUse.type; entry.AppleDosType = appleProDosSystemUse.type;
break; break;
case AppleId.HFS: case AppleId.HFS:
AppleHFSSystemUse appleHfsSystemUse = AppleHFSSystemUse appleHfsSystemUse =
Marshal.ByteArrayToStructureBigEndian<AppleHFSSystemUse>(data, systemAreaStart, Marshal.ByteArrayToStructureBigEndian<AppleHFSSystemUse>(data, systemAreaOff,
systemAreaLength); Marshal
.SizeOf<
AppleHFSSystemUse
>());
hasResourceFork = true; hasResourceFork = true;
entry.FinderInfo = new FinderInfo(); entry.FinderInfo = new FinderInfo();
entry.FinderInfo.fdCreator = appleHfsSystemUse.creator; entry.FinderInfo.fdCreator = appleHfsSystemUse.creator;
entry.FinderInfo.fdFlags = (FinderFlags)appleHfsSystemUse.finder_flags; entry.FinderInfo.fdFlags = (FinderFlags)appleHfsSystemUse.finder_flags;
entry.FinderInfo.fdType = appleHfsSystemUse.type; entry.FinderInfo.fdType = appleHfsSystemUse.type;
break; break;
} }
}
else if(systemAreaSignature == APPLE_MAGIC_OLD)
{
AppleOldId appleId = (AppleOldId)data[systemAreaStart + 2];
switch(appleId) systemAreaOff += appleLength;
{ break;
case AppleOldId.ProDOS: case APPLE_MAGIC_OLD:
AppleProDOSOldSystemUse appleProDosOldSystemUse = AppleOldId appleOldId = (AppleOldId)data[systemAreaOff + 2];
Marshal.ByteArrayToStructureLittleEndian<AppleProDOSOldSystemUse>(data,
systemAreaStart,
systemAreaLength);
entry.AppleProDosType = appleProDosOldSystemUse.aux_type;
entry.AppleDosType = appleProDosOldSystemUse.type;
break; switch(appleOldId)
case AppleOldId.TypeCreator: {
case AppleOldId.TypeCreatorBundle: case AppleOldId.ProDOS:
AppleHFSTypeCreatorSystemUse appleHfsTypeCreatorSystemUse = AppleProDOSOldSystemUse appleProDosOldSystemUse =
Marshal.ByteArrayToStructureBigEndian<AppleHFSTypeCreatorSystemUse>(data, Marshal.ByteArrayToStructureLittleEndian<AppleProDOSOldSystemUse>(data,
systemAreaStart, systemAreaOff,
systemAreaLength); Marshal
.SizeOf<
AppleProDOSOldSystemUse
>());
entry.AppleProDosType = appleProDosOldSystemUse.aux_type;
entry.AppleDosType = appleProDosOldSystemUse.type;
hasResourceFork = true; systemAreaOff += Marshal.SizeOf<AppleProDOSOldSystemUse>();
break;
case AppleOldId.TypeCreator:
case AppleOldId.TypeCreatorBundle:
AppleHFSTypeCreatorSystemUse appleHfsTypeCreatorSystemUse =
Marshal.ByteArrayToStructureBigEndian<AppleHFSTypeCreatorSystemUse>(data,
systemAreaOff,
Marshal
.SizeOf<
AppleHFSTypeCreatorSystemUse
>());
entry.FinderInfo = new FinderInfo(); hasResourceFork = true;
entry.FinderInfo.fdCreator = appleHfsTypeCreatorSystemUse.creator;
entry.FinderInfo.fdType = appleHfsTypeCreatorSystemUse.type;
break; entry.FinderInfo = new FinderInfo();
case AppleOldId.TypeCreatorIcon: entry.FinderInfo.fdCreator = appleHfsTypeCreatorSystemUse.creator;
case AppleOldId.TypeCreatorIconBundle: entry.FinderInfo.fdType = appleHfsTypeCreatorSystemUse.type;
AppleHFSIconSystemUse appleHfsIconSystemUse =
Marshal.ByteArrayToStructureBigEndian<AppleHFSIconSystemUse>(data, systemAreaStart,
systemAreaLength);
hasResourceFork = true; systemAreaOff += Marshal.SizeOf<AppleHFSTypeCreatorSystemUse>();
break;
case AppleOldId.TypeCreatorIcon:
case AppleOldId.TypeCreatorIconBundle:
AppleHFSIconSystemUse appleHfsIconSystemUse =
Marshal.ByteArrayToStructureBigEndian<AppleHFSIconSystemUse>(data,
systemAreaOff,
Marshal
.SizeOf<
AppleHFSIconSystemUse
>());
entry.FinderInfo = new FinderInfo(); hasResourceFork = true;
entry.FinderInfo.fdCreator = appleHfsIconSystemUse.creator;
entry.FinderInfo.fdType = appleHfsIconSystemUse.type;
entry.AppleIcon = appleHfsIconSystemUse.icon;
break; entry.FinderInfo = new FinderInfo();
case AppleOldId.HFS: entry.FinderInfo.fdCreator = appleHfsIconSystemUse.creator;
AppleHFSOldSystemUse appleHfsSystemUse = entry.FinderInfo.fdType = appleHfsIconSystemUse.type;
Marshal.ByteArrayToStructureBigEndian<AppleHFSOldSystemUse>(data, systemAreaStart, entry.AppleIcon = appleHfsIconSystemUse.icon;
systemAreaLength);
hasResourceFork = true; systemAreaOff += Marshal.SizeOf<AppleHFSIconSystemUse>();
break;
case AppleOldId.HFS:
AppleHFSOldSystemUse appleHfsSystemUse =
Marshal.ByteArrayToStructureBigEndian<AppleHFSOldSystemUse>(data, systemAreaOff,
Marshal
.SizeOf<
AppleHFSOldSystemUse
>());
entry.FinderInfo = new FinderInfo(); hasResourceFork = true;
entry.FinderInfo.fdCreator = appleHfsSystemUse.creator;
entry.FinderInfo.fdFlags = (FinderFlags)appleHfsSystemUse.finder_flags;
entry.FinderInfo.fdType = appleHfsSystemUse.type;
break; entry.FinderInfo = new FinderInfo();
default: throw new ArgumentOutOfRangeException(); entry.FinderInfo.fdCreator = appleHfsSystemUse.creator;
} entry.FinderInfo.fdFlags = (FinderFlags)appleHfsSystemUse.finder_flags;
entry.FinderInfo.fdType = appleHfsSystemUse.type;
systemAreaOff += Marshal.SizeOf<AppleHFSOldSystemUse>();
break;
default:
// Cannot continue as we don't know this structure size
systemAreaOff = systemAreaEnd;
break;
}
break;
case XA_MAGIC:
entry.XA = Marshal.ByteArrayToStructureBigEndian<CdromXa>(data, systemAreaOff,
Marshal.SizeOf<CdromXa>());
systemAreaOff += Marshal.SizeOf<CdromXa>();
break;
default:
// Cannot continue as we don't know this structure size
systemAreaOff = systemAreaEnd;
break;
} }
} }

View File

@@ -118,6 +118,20 @@ namespace DiscImageChef.Filesystems.ISO9660
if(entry.AppleIcon != null) stat.Attributes |= FileAttributes.HasCustomIcon; if(entry.AppleIcon != null) stat.Attributes |= FileAttributes.HasCustomIcon;
if(entry.XA != null)
{
if(entry.XA.Value.attributes.HasFlag(XaAttributes.GroupExecute)) stat.Mode |= 8;
if(entry.XA.Value.attributes.HasFlag(XaAttributes.GroupRead)) stat.Mode |= 32;
if(entry.XA.Value.attributes.HasFlag(XaAttributes.OwnerExecute)) stat.Mode |= 64;
if(entry.XA.Value.attributes.HasFlag(XaAttributes.OwnerRead)) stat.Mode |= 256;
if(entry.XA.Value.attributes.HasFlag(XaAttributes.SystemExecute)) stat.Mode |= 1;
if(entry.XA.Value.attributes.HasFlag(XaAttributes.SystemRead)) stat.Mode |= 4;
stat.UID = entry.XA.Value.user;
stat.GID = entry.XA.Value.group;
stat.Inode = entry.XA.Value.filenumber;
}
if(entry.AssociatedFile is null || entry.AssociatedFile.Extent == 0 || entry.AssociatedFile.Size == 0) if(entry.AssociatedFile is null || entry.AssociatedFile.Extent == 0 || entry.AssociatedFile.Size == 0)
return Errno.NoError; return Errno.NoError;
@@ -133,12 +147,12 @@ namespace DiscImageChef.Filesystems.ISO9660
stat.GID = ear.group; stat.GID = ear.group;
stat.Mode = 0; stat.Mode = 0;
if(ear.permissions.HasFlag(Permissions.GroupExecute)) stat.Mode += 8; if(ear.permissions.HasFlag(Permissions.GroupExecute)) stat.Mode |= 8;
if(ear.permissions.HasFlag(Permissions.GroupRead)) stat.Mode += 32; if(ear.permissions.HasFlag(Permissions.GroupRead)) stat.Mode |= 32;
if(ear.permissions.HasFlag(Permissions.OwnerExecute)) stat.Mode += 64; if(ear.permissions.HasFlag(Permissions.OwnerExecute)) stat.Mode |= 64;
if(ear.permissions.HasFlag(Permissions.OwnerRead)) stat.Mode += 256; if(ear.permissions.HasFlag(Permissions.OwnerRead)) stat.Mode |= 256;
if(ear.permissions.HasFlag(Permissions.OtherExecute)) stat.Mode += 1; if(ear.permissions.HasFlag(Permissions.OtherExecute)) stat.Mode |= 1;
if(ear.permissions.HasFlag(Permissions.OtherRead)) stat.Mode += 4; if(ear.permissions.HasFlag(Permissions.OtherRead)) stat.Mode |= 4;
stat.CreationTimeUtc = DateHandlers.Iso9660ToDateTime(ear.creation_date); stat.CreationTimeUtc = DateHandlers.Iso9660ToDateTime(ear.creation_date);
stat.LastWriteTimeUtc = DateHandlers.Iso9660ToDateTime(ear.modification_date); stat.LastWriteTimeUtc = DateHandlers.Iso9660ToDateTime(ear.modification_date);

View File

@@ -71,6 +71,7 @@ namespace DiscImageChef.Filesystems.ISO9660
public uint Size; public uint Size;
public DateTime? Timestamp; public DateTime? Timestamp;
public ushort VolumeSequenceNumber; public ushort VolumeSequenceNumber;
public CdromXa? XA;
public override string ToString() => Filename; public override string ToString() => Filename;
} }

View File

@@ -40,13 +40,13 @@ namespace DiscImageChef.Filesystems.ISO9660
[StructLayout(LayoutKind.Sequential, Pack = 1)] [StructLayout(LayoutKind.Sequential, Pack = 1)]
struct CdromXa struct CdromXa
{ {
public ushort group;
public ushort user;
public XaAttributes attributes; public XaAttributes attributes;
public ushort signature;
public byte filenumber; public byte filenumber;
public ushort group;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)] [MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
public byte[] reserved; public byte[] reserved;
public ushort signature;
public ushort user;
} }
} }
} }