From a47d8e13f0a092b8c574235ce14464e1d5441d9b Mon Sep 17 00:00:00 2001 From: Natalia Portillo Date: Sun, 28 Jul 2019 21:33:05 +0100 Subject: [PATCH] Decode "SL" system area. --- DiscImageChef.Filesystems/ISO9660/Dir.cs | 48 ++++++++++++++++++- DiscImageChef.Filesystems/ISO9660/File.cs | 17 +++++++ DiscImageChef.Filesystems/ISO9660/ISO9660.cs | 7 --- .../ISO9660/Structs/Internal.cs | 1 + 4 files changed, 64 insertions(+), 9 deletions(-) diff --git a/DiscImageChef.Filesystems/ISO9660/Dir.cs b/DiscImageChef.Filesystems/ISO9660/Dir.cs index cb1865ad8..bc3308f72 100644 --- a/DiscImageChef.Filesystems/ISO9660/Dir.cs +++ b/DiscImageChef.Filesystems/ISO9660/Dir.cs @@ -248,6 +248,8 @@ namespace DiscImageChef.Filesystems.ISO9660 { int systemAreaOff = start; hasResourceFork = false; + bool continueSymlink = false; + bool continueSymlinkComponent = false; while(systemAreaOff + 2 <= end) { @@ -459,10 +461,52 @@ namespace DiscImageChef.Filesystems.ISO9660 systemAreaOff += pnLength; break; case RRIP_SYMLINK: - // TODO byte slLength = data[systemAreaOff + 2]; - systemAreaOff += slLength; + SymbolicLink sl = + Marshal.ByteArrayToStructureLittleEndian(data, systemAreaOff, + Marshal.SizeOf()); + + SymbolicLinkComponent slc = + Marshal.ByteArrayToStructureLittleEndian(data, + systemAreaOff + + Marshal + .SizeOf(), + Marshal + .SizeOf< + SymbolicLinkComponent + >()); + + if(!continueSymlink || entry.SymbolicLink is null) entry.SymbolicLink = ""; + + if(slc.flags.HasFlag(SymlinkComponentFlags.Root)) entry.SymbolicLink = "/"; + if(slc.flags.HasFlag(SymlinkComponentFlags.Current)) entry.SymbolicLink += "."; + if(slc.flags.HasFlag(SymlinkComponentFlags.Parent)) entry.SymbolicLink += ".."; + + if(!continueSymlinkComponent && !slc.flags.HasFlag(SymlinkComponentFlags.Root)) + entry.SymbolicLink += "/"; + + entry.SymbolicLink += slc.flags.HasFlag(SymlinkComponentFlags.Networkname) + ? Environment.MachineName + : joliet + ? Encoding.BigEndianUnicode.GetString(data, + systemAreaOff + + Marshal + .SizeOf() + + Marshal + .SizeOf< + SymbolicLinkComponent + >(), slc.length) + : Encoding.GetString(data, + systemAreaOff + + Marshal.SizeOf() + + Marshal.SizeOf(), + slc.length); + + continueSymlink = entry.Flags.HasFlag(SymlinkFlags.Continue); + continueSymlinkComponent = entry.Flags.HasFlag(SymlinkComponentFlags.Continue); + + systemAreaOff += slLength; break; case RRIP_NAME: byte nmLength = data[systemAreaOff + 2]; diff --git a/DiscImageChef.Filesystems/ISO9660/File.cs b/DiscImageChef.Filesystems/ISO9660/File.cs index 081f1c14d..6b8430f8f 100644 --- a/DiscImageChef.Filesystems/ISO9660/File.cs +++ b/DiscImageChef.Filesystems/ISO9660/File.cs @@ -40,6 +40,7 @@ namespace DiscImageChef.Filesystems.ISO9660 return Errno.NoError; } + // TODO: Resolve symbolic link public Errno Read(string path, long offset, long size, ref byte[] buf) { buf = null; @@ -195,6 +196,8 @@ namespace DiscImageChef.Filesystems.ISO9660 if(entry.RripBackup != null) stat.BackupTimeUtc = DecodeIsoDateTime(entry.RripBackup); + if(entry.SymbolicLink != null) stat.Attributes |= FileAttributes.Symlink; + if(entry.AssociatedFile is null || entry.AssociatedFile.Extent == 0 || entry.AssociatedFile.Size == 0) return Errno.NoError; @@ -223,6 +226,20 @@ namespace DiscImageChef.Filesystems.ISO9660 return Errno.NoError; } + public Errno ReadLink(string path, out string dest) + { + dest = null; + + Errno err = GetFileEntry(path, out DecodedDirectoryEntry entry); + if(err != Errno.NoError) return err; + + if(entry.SymbolicLink is null) return Errno.InvalidArgument; + + dest = entry.SymbolicLink; + + return Errno.NoError; + } + Errno GetFileEntry(string path, out DecodedDirectoryEntry entry) { entry = null; diff --git a/DiscImageChef.Filesystems/ISO9660/ISO9660.cs b/DiscImageChef.Filesystems/ISO9660/ISO9660.cs index cd54d3312..45d6cd59a 100644 --- a/DiscImageChef.Filesystems/ISO9660/ISO9660.cs +++ b/DiscImageChef.Filesystems/ISO9660/ISO9660.cs @@ -71,13 +71,6 @@ namespace DiscImageChef.Filesystems.ISO9660 {"romeo", "Primary Volume Descriptor using the specified encoding codepage"} }; - public Errno ReadLink(string path, out string dest) - { - dest = null; - - return Errno.NotSupported; - } - static Dictionary GetDefaultOptions() => new Dictionary {{"debug", false.ToString()}}; } diff --git a/DiscImageChef.Filesystems/ISO9660/Structs/Internal.cs b/DiscImageChef.Filesystems/ISO9660/Structs/Internal.cs index cb58fef37..5181e9c06 100644 --- a/DiscImageChef.Filesystems/ISO9660/Structs/Internal.cs +++ b/DiscImageChef.Filesystems/ISO9660/Structs/Internal.cs @@ -82,6 +82,7 @@ namespace DiscImageChef.Filesystems.ISO9660 public byte[] RripExpiration; public byte[] RripModify; public uint Size; + public string SymbolicLink; public DateTime? Timestamp; public ushort VolumeSequenceNumber; public CdromXa? XA;