diff --git a/DiscImageChef.Filesystems/ISO9660/Dir.cs b/DiscImageChef.Filesystems/ISO9660/Dir.cs index 023ff9fca..09eb5215d 100644 --- a/DiscImageChef.Filesystems/ISO9660/Dir.cs +++ b/DiscImageChef.Filesystems/ISO9660/Dir.cs @@ -200,99 +200,146 @@ namespace DiscImageChef.Filesystems.ISO9660 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) - { - case AppleId.ProDOS: - AppleProDOSSystemUse appleProDosSystemUse = - Marshal.ByteArrayToStructureLittleEndian(data, - systemAreaStart, - systemAreaLength); + switch(appleId) + { + case AppleId.ProDOS: + AppleProDOSSystemUse appleProDosSystemUse = + Marshal.ByteArrayToStructureLittleEndian(data, + systemAreaOff, + Marshal + .SizeOf< + AppleProDOSSystemUse + >()); - entry.AppleProDosType = appleProDosSystemUse.aux_type; - entry.AppleDosType = appleProDosSystemUse.type; + entry.AppleProDosType = appleProDosSystemUse.aux_type; + entry.AppleDosType = appleProDosSystemUse.type; - break; - case AppleId.HFS: - AppleHFSSystemUse appleHfsSystemUse = - Marshal.ByteArrayToStructureBigEndian(data, systemAreaStart, - systemAreaLength); + break; + case AppleId.HFS: + AppleHFSSystemUse appleHfsSystemUse = + Marshal.ByteArrayToStructureBigEndian(data, systemAreaOff, + Marshal + .SizeOf< + AppleHFSSystemUse + >()); - hasResourceFork = true; + hasResourceFork = true; - entry.FinderInfo = new FinderInfo(); - entry.FinderInfo.fdCreator = appleHfsSystemUse.creator; - entry.FinderInfo.fdFlags = (FinderFlags)appleHfsSystemUse.finder_flags; - entry.FinderInfo.fdType = appleHfsSystemUse.type; + entry.FinderInfo = new FinderInfo(); + entry.FinderInfo.fdCreator = appleHfsSystemUse.creator; + entry.FinderInfo.fdFlags = (FinderFlags)appleHfsSystemUse.finder_flags; + entry.FinderInfo.fdType = appleHfsSystemUse.type; - break; - } - } - else if(systemAreaSignature == APPLE_MAGIC_OLD) - { - AppleOldId appleId = (AppleOldId)data[systemAreaStart + 2]; + break; + } - switch(appleId) - { - case AppleOldId.ProDOS: - AppleProDOSOldSystemUse appleProDosOldSystemUse = - Marshal.ByteArrayToStructureLittleEndian(data, - systemAreaStart, - systemAreaLength); - entry.AppleProDosType = appleProDosOldSystemUse.aux_type; - entry.AppleDosType = appleProDosOldSystemUse.type; + systemAreaOff += appleLength; + break; + case APPLE_MAGIC_OLD: + AppleOldId appleOldId = (AppleOldId)data[systemAreaOff + 2]; - break; - case AppleOldId.TypeCreator: - case AppleOldId.TypeCreatorBundle: - AppleHFSTypeCreatorSystemUse appleHfsTypeCreatorSystemUse = - Marshal.ByteArrayToStructureBigEndian(data, - systemAreaStart, - systemAreaLength); + switch(appleOldId) + { + case AppleOldId.ProDOS: + AppleProDOSOldSystemUse appleProDosOldSystemUse = + Marshal.ByteArrayToStructureLittleEndian(data, + systemAreaOff, + Marshal + .SizeOf< + AppleProDOSOldSystemUse + >()); + entry.AppleProDosType = appleProDosOldSystemUse.aux_type; + entry.AppleDosType = appleProDosOldSystemUse.type; - hasResourceFork = true; + systemAreaOff += Marshal.SizeOf(); + break; + case AppleOldId.TypeCreator: + case AppleOldId.TypeCreatorBundle: + AppleHFSTypeCreatorSystemUse appleHfsTypeCreatorSystemUse = + Marshal.ByteArrayToStructureBigEndian(data, + systemAreaOff, + Marshal + .SizeOf< + AppleHFSTypeCreatorSystemUse + >()); - entry.FinderInfo = new FinderInfo(); - entry.FinderInfo.fdCreator = appleHfsTypeCreatorSystemUse.creator; - entry.FinderInfo.fdType = appleHfsTypeCreatorSystemUse.type; + hasResourceFork = true; - break; - case AppleOldId.TypeCreatorIcon: - case AppleOldId.TypeCreatorIconBundle: - AppleHFSIconSystemUse appleHfsIconSystemUse = - Marshal.ByteArrayToStructureBigEndian(data, systemAreaStart, - systemAreaLength); + entry.FinderInfo = new FinderInfo(); + entry.FinderInfo.fdCreator = appleHfsTypeCreatorSystemUse.creator; + entry.FinderInfo.fdType = appleHfsTypeCreatorSystemUse.type; - hasResourceFork = true; + systemAreaOff += Marshal.SizeOf(); + break; + case AppleOldId.TypeCreatorIcon: + case AppleOldId.TypeCreatorIconBundle: + AppleHFSIconSystemUse appleHfsIconSystemUse = + Marshal.ByteArrayToStructureBigEndian(data, + systemAreaOff, + Marshal + .SizeOf< + AppleHFSIconSystemUse + >()); - entry.FinderInfo = new FinderInfo(); - entry.FinderInfo.fdCreator = appleHfsIconSystemUse.creator; - entry.FinderInfo.fdType = appleHfsIconSystemUse.type; - entry.AppleIcon = appleHfsIconSystemUse.icon; + hasResourceFork = true; - break; - case AppleOldId.HFS: - AppleHFSOldSystemUse appleHfsSystemUse = - Marshal.ByteArrayToStructureBigEndian(data, systemAreaStart, - systemAreaLength); + entry.FinderInfo = new FinderInfo(); + entry.FinderInfo.fdCreator = appleHfsIconSystemUse.creator; + entry.FinderInfo.fdType = appleHfsIconSystemUse.type; + entry.AppleIcon = appleHfsIconSystemUse.icon; - hasResourceFork = true; + systemAreaOff += Marshal.SizeOf(); + break; + case AppleOldId.HFS: + AppleHFSOldSystemUse appleHfsSystemUse = + Marshal.ByteArrayToStructureBigEndian(data, systemAreaOff, + Marshal + .SizeOf< + AppleHFSOldSystemUse + >()); - entry.FinderInfo = new FinderInfo(); - entry.FinderInfo.fdCreator = appleHfsSystemUse.creator; - entry.FinderInfo.fdFlags = (FinderFlags)appleHfsSystemUse.finder_flags; - entry.FinderInfo.fdType = appleHfsSystemUse.type; + hasResourceFork = true; - break; - default: throw new ArgumentOutOfRangeException(); - } + entry.FinderInfo = new FinderInfo(); + entry.FinderInfo.fdCreator = appleHfsSystemUse.creator; + entry.FinderInfo.fdFlags = (FinderFlags)appleHfsSystemUse.finder_flags; + entry.FinderInfo.fdType = appleHfsSystemUse.type; + + systemAreaOff += Marshal.SizeOf(); + break; + default: + // Cannot continue as we don't know this structure size + systemAreaOff = systemAreaEnd; + break; + } + + break; + case XA_MAGIC: + entry.XA = Marshal.ByteArrayToStructureBigEndian(data, systemAreaOff, + Marshal.SizeOf()); + + systemAreaOff += Marshal.SizeOf(); + break; + default: + // Cannot continue as we don't know this structure size + systemAreaOff = systemAreaEnd; + break; } } diff --git a/DiscImageChef.Filesystems/ISO9660/File.cs b/DiscImageChef.Filesystems/ISO9660/File.cs index b6a26c7ff..eacc30f32 100644 --- a/DiscImageChef.Filesystems/ISO9660/File.cs +++ b/DiscImageChef.Filesystems/ISO9660/File.cs @@ -118,6 +118,20 @@ namespace DiscImageChef.Filesystems.ISO9660 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) return Errno.NoError; @@ -133,12 +147,12 @@ namespace DiscImageChef.Filesystems.ISO9660 stat.GID = ear.group; stat.Mode = 0; - if(ear.permissions.HasFlag(Permissions.GroupExecute)) stat.Mode += 8; - if(ear.permissions.HasFlag(Permissions.GroupRead)) stat.Mode += 32; - if(ear.permissions.HasFlag(Permissions.OwnerExecute)) stat.Mode += 64; - if(ear.permissions.HasFlag(Permissions.OwnerRead)) stat.Mode += 256; - if(ear.permissions.HasFlag(Permissions.OtherExecute)) stat.Mode += 1; - if(ear.permissions.HasFlag(Permissions.OtherRead)) stat.Mode += 4; + if(ear.permissions.HasFlag(Permissions.GroupExecute)) stat.Mode |= 8; + if(ear.permissions.HasFlag(Permissions.GroupRead)) stat.Mode |= 32; + if(ear.permissions.HasFlag(Permissions.OwnerExecute)) stat.Mode |= 64; + if(ear.permissions.HasFlag(Permissions.OwnerRead)) stat.Mode |= 256; + if(ear.permissions.HasFlag(Permissions.OtherExecute)) stat.Mode |= 1; + if(ear.permissions.HasFlag(Permissions.OtherRead)) stat.Mode |= 4; stat.CreationTimeUtc = DateHandlers.Iso9660ToDateTime(ear.creation_date); stat.LastWriteTimeUtc = DateHandlers.Iso9660ToDateTime(ear.modification_date); diff --git a/DiscImageChef.Filesystems/ISO9660/Structs/Internal.cs b/DiscImageChef.Filesystems/ISO9660/Structs/Internal.cs index 1ec78bd54..80464fb4d 100644 --- a/DiscImageChef.Filesystems/ISO9660/Structs/Internal.cs +++ b/DiscImageChef.Filesystems/ISO9660/Structs/Internal.cs @@ -71,6 +71,7 @@ namespace DiscImageChef.Filesystems.ISO9660 public uint Size; public DateTime? Timestamp; public ushort VolumeSequenceNumber; + public CdromXa? XA; public override string ToString() => Filename; } diff --git a/DiscImageChef.Filesystems/ISO9660/Structs/XA.cs b/DiscImageChef.Filesystems/ISO9660/Structs/XA.cs index 796339aee..ddfdb150f 100644 --- a/DiscImageChef.Filesystems/ISO9660/Structs/XA.cs +++ b/DiscImageChef.Filesystems/ISO9660/Structs/XA.cs @@ -40,13 +40,13 @@ namespace DiscImageChef.Filesystems.ISO9660 [StructLayout(LayoutKind.Sequential, Pack = 1)] struct CdromXa { - public ushort group; - public ushort user; public XaAttributes attributes; - public ushort signature; public byte filenumber; + public ushort group; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)] public byte[] reserved; + public ushort signature; + public ushort user; } } } \ No newline at end of file