diff --git a/DiscImageChef.CommonTypes/Structs/Filesystems.cs b/DiscImageChef.CommonTypes/Structs/Filesystems.cs index 341588427..f85c27422 100644 --- a/DiscImageChef.CommonTypes/Structs/Filesystems.cs +++ b/DiscImageChef.CommonTypes/Structs/Filesystems.cs @@ -147,7 +147,9 @@ namespace DiscImageChef.CommonTypes.Structs /// If file is deleted, contents should be stored, for a possible future undeletion Undeletable = 0x800000000000, /// File is a pipe - Pipe = 0x1000000000000 + Pipe = 0x1000000000000, + /// File is a socket + Socket = 0x2000000000000 } /// diff --git a/DiscImageChef.Filesystems/ISO9660/Consts/RRIP.cs b/DiscImageChef.Filesystems/ISO9660/Consts/RRIP.cs index a4b3a5e40..a78427f98 100644 --- a/DiscImageChef.Filesystems/ISO9660/Consts/RRIP.cs +++ b/DiscImageChef.Filesystems/ISO9660/Consts/RRIP.cs @@ -50,18 +50,18 @@ namespace DiscImageChef.Filesystems.ISO9660 [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, + OwnerRead = 0x0100, + OwnerWrite = 0x0080, + OwnerExecute = 0x0040, + GroupRead = 0x0020, + GroupWrite = 0x0010, + GroupExecute = 0x0008, + OtherRead = 0x0004, + OtherWrite = 0x0002, + OtherExecute = 0x0001, + SetUID = 0x0800, + SetGid = 0x0400, + IsVTX = 0x0200, Socket = 0xC000, Symlink = 0xA000, Regular = 0x8000, diff --git a/DiscImageChef.Filesystems/ISO9660/Dir.cs b/DiscImageChef.Filesystems/ISO9660/Dir.cs index d6dcd4ca8..298ac00ac 100644 --- a/DiscImageChef.Filesystems/ISO9660/Dir.cs +++ b/DiscImageChef.Filesystems/ISO9660/Dir.cs @@ -435,6 +435,24 @@ namespace DiscImageChef.Filesystems.ISO9660 break; case RRIP_POSIX_ATTRIBUTES: + byte pxLength = data[systemAreaOff + 2]; + + if(pxLength == 36) + entry.PosixAttributesOld = + Marshal.ByteArrayToStructureLittleEndian(data, systemAreaOff, + Marshal + .SizeOf< + PosixAttributesOld + >()); + else if(pxLength >= 44) + entry.PosixAttributes = + Marshal.ByteArrayToStructureLittleEndian(data, systemAreaOff, + Marshal + .SizeOf()); + + systemAreaOff += pxLength; + break; case RRIP_POSIX_DEV_NO: case RRIP_SYMLINK: case RRIP_NAME: diff --git a/DiscImageChef.Filesystems/ISO9660/File.cs b/DiscImageChef.Filesystems/ISO9660/File.cs index e632aed30..500093d7e 100644 --- a/DiscImageChef.Filesystems/ISO9660/File.cs +++ b/DiscImageChef.Filesystems/ISO9660/File.cs @@ -132,14 +132,49 @@ namespace DiscImageChef.Filesystems.ISO9660 stat.Inode = entry.XA.Value.filenumber; } + if(entry.PosixAttributes != null) + { + stat.Mode = (uint?)entry.PosixAttributes.Value.st_mode & 0x0FFF; + if(entry.PosixAttributes.Value.st_mode.HasFlag(PosixMode.Block)) + stat.Attributes |= FileAttributes.BlockDevice; + if(entry.PosixAttributes.Value.st_mode.HasFlag(PosixMode.Character)) + stat.Attributes |= FileAttributes.CharDevice; + if(entry.PosixAttributes.Value.st_mode.HasFlag(PosixMode.Pipe)) stat.Attributes |= FileAttributes.Pipe; + if(entry.PosixAttributes.Value.st_mode.HasFlag(PosixMode.Socket)) + stat.Attributes |= FileAttributes.Socket; + if(entry.PosixAttributes.Value.st_mode.HasFlag(PosixMode.Symlink)) + stat.Attributes |= FileAttributes.Symlink; + stat.Links = entry.PosixAttributes.Value.st_nlink; + stat.UID = entry.PosixAttributes.Value.st_uid; + stat.GID = entry.PosixAttributes.Value.st_gid; + stat.Inode = entry.PosixAttributes.Value.st_ino; + } + else if(entry.PosixAttributesOld != null) + { + stat.Mode = (uint?)entry.PosixAttributesOld.Value.st_mode & 0x0FFF; + if(entry.PosixAttributesOld.Value.st_mode.HasFlag(PosixMode.Block)) + stat.Attributes |= FileAttributes.BlockDevice; + if(entry.PosixAttributesOld.Value.st_mode.HasFlag(PosixMode.Character)) + stat.Attributes |= FileAttributes.CharDevice; + if(entry.PosixAttributesOld.Value.st_mode.HasFlag(PosixMode.Pipe)) + stat.Attributes |= FileAttributes.Pipe; + if(entry.PosixAttributesOld.Value.st_mode.HasFlag(PosixMode.Socket)) + stat.Attributes |= FileAttributes.Socket; + if(entry.PosixAttributesOld.Value.st_mode.HasFlag(PosixMode.Symlink)) + stat.Attributes |= FileAttributes.Symlink; + stat.Links = entry.PosixAttributesOld.Value.st_nlink; + stat.UID = entry.PosixAttributesOld.Value.st_uid; + stat.GID = entry.PosixAttributesOld.Value.st_gid; + } + if(entry.AmigaProtection != null) { - if(entry.AmigaProtection.Value.Multiuser.HasFlag(AmigaMultiuser.GroupExec)) stat.Mode |= 8; - if(entry.AmigaProtection.Value.Multiuser.HasFlag(AmigaMultiuser.GroupRead)) stat.Mode |= 32; - if(entry.AmigaProtection.Value.Multiuser.HasFlag(AmigaMultiuser.GroupWrite)) stat.Mode |= 16; - if(entry.AmigaProtection.Value.Multiuser.HasFlag(AmigaMultiuser.OtherExec)) stat.Mode |= 1; - if(entry.AmigaProtection.Value.Multiuser.HasFlag(AmigaMultiuser.OtherRead)) stat.Mode |= 4; - if(entry.AmigaProtection.Value.Multiuser.HasFlag(AmigaMultiuser.OtherWrite)) stat.Mode |= 2; + if(entry.AmigaProtection.Value.Multiuser.HasFlag(AmigaMultiuser.GroupExec)) stat.Mode |= 8; + if(entry.AmigaProtection.Value.Multiuser.HasFlag(AmigaMultiuser.GroupRead)) stat.Mode |= 32; + if(entry.AmigaProtection.Value.Multiuser.HasFlag(AmigaMultiuser.GroupWrite)) stat.Mode |= 16; + if(entry.AmigaProtection.Value.Multiuser.HasFlag(AmigaMultiuser.OtherExec)) stat.Mode |= 1; + if(entry.AmigaProtection.Value.Multiuser.HasFlag(AmigaMultiuser.OtherRead)) stat.Mode |= 4; + if(entry.AmigaProtection.Value.Multiuser.HasFlag(AmigaMultiuser.OtherWrite)) stat.Mode |= 2; if(entry.AmigaProtection.Value.Protection.HasFlag(AmigaAttributes.OwnerExec)) stat.Mode |= 64; if(entry.AmigaProtection.Value.Protection.HasFlag(AmigaAttributes.OwnerRead)) stat.Mode |= 256; if(entry.AmigaProtection.Value.Protection.HasFlag(AmigaAttributes.OwnerWrite)) stat.Mode |= 128; diff --git a/DiscImageChef.Filesystems/ISO9660/Structs/Internal.cs b/DiscImageChef.Filesystems/ISO9660/Structs/Internal.cs index bcb3f7b65..b498d58c7 100644 --- a/DiscImageChef.Filesystems/ISO9660/Structs/Internal.cs +++ b/DiscImageChef.Filesystems/ISO9660/Structs/Internal.cs @@ -69,6 +69,8 @@ namespace DiscImageChef.Filesystems.ISO9660 public FinderInfo FinderInfo; public FileFlags Flags; public byte Interleave; + public PosixAttributes? PosixAttributes; + public PosixAttributesOld? PosixAttributesOld; public DecodedDirectoryEntry ResourceFork; public uint Size; public DateTime? Timestamp; diff --git a/DiscImageChef.Filesystems/ISO9660/Structs/RRIP.cs b/DiscImageChef.Filesystems/ISO9660/Structs/RRIP.cs index 3fd3cbe34..af0edf246 100644 --- a/DiscImageChef.Filesystems/ISO9660/Structs/RRIP.cs +++ b/DiscImageChef.Filesystems/ISO9660/Structs/RRIP.cs @@ -36,99 +36,117 @@ namespace DiscImageChef.Filesystems.ISO9660 { public partial class ISO9660 { + // RRIP 1.10 + [StructLayout(LayoutKind.Sequential, Pack = 1)] + struct PosixAttributesOld + { + public readonly ushort signature; + public readonly byte length; + public readonly byte version; + public readonly PosixMode st_mode; + public readonly PosixMode st_mode_be; + public readonly uint st_nlink; + public readonly uint st_nlink_be; + public readonly uint st_uid; + public readonly uint st_uid_be; + public readonly uint st_gid; + public readonly uint st_gid_be; + } + + // RRIP 1.12 [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; + public readonly ushort signature; + public readonly byte length; + public readonly byte version; + public readonly PosixMode st_mode; + public readonly PosixMode st_mode_be; + public readonly uint st_nlink; + public readonly uint st_nlink_be; + public readonly uint st_uid; + public readonly uint st_uid_be; + public readonly uint st_gid; + public readonly uint st_gid_be; + public readonly uint st_ino; + public readonly 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; + public readonly ushort signature; + public readonly byte length; + public readonly byte version; + public readonly uint dev_t_high; + public readonly uint dev_t_high_be; + public readonly uint dev_t_low; + public readonly uint dev_t_low_be; } [StructLayout(LayoutKind.Sequential, Pack = 1)] struct SymbolicLink { - public ushort signature; - public byte length; - public byte version; - public SymlinkFlags flags; + public readonly ushort signature; + public readonly byte length; + public readonly byte version; + public readonly 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; + public readonly SymlinkComponentFlags flags; + public readonly 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; + public readonly ushort signature; + public readonly byte length; + public readonly byte version; + public readonly 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; + public readonly ushort signature; + public readonly byte length; + public readonly byte version; + public readonly uint child_dir_lba; + public readonly 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; + public readonly ushort signature; + public readonly byte length; + public readonly byte version; + public readonly uint parent_dir_lba; + public readonly uint parent_dir_lba_be; } [StructLayout(LayoutKind.Sequential, Pack = 1)] struct RelocatedDirectory { - public ushort signature; - public byte length; - public byte version; + public readonly ushort signature; + public readonly byte length; + public readonly byte version; } [StructLayout(LayoutKind.Sequential, Pack = 1)] struct Timestamps { - public ushort signature; - public byte length; - public byte version; - public TimestampFlags flags; + public readonly ushort signature; + public readonly byte length; + public readonly byte version; + public readonly 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 @@ -142,14 +160,14 @@ namespace DiscImageChef.Filesystems.ISO9660 [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; + public readonly ushort signature; + public readonly byte length; + public readonly byte version; + public readonly uint virtual_size_high; + public readonly uint virtual_size_high_be; + public readonly uint virtual_size_low; + public readonly uint virtual_size_low_be; + public readonly byte table_depth; } } } \ No newline at end of file