Decode TRANS.TBL;1.

This commit is contained in:
2019-07-31 01:02:56 +01:00
parent a2314ff9d5
commit 25bf3737d3
3 changed files with 75 additions and 2 deletions

View File

@@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.IO;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using DiscImageChef.CommonTypes.Structs; using DiscImageChef.CommonTypes.Structs;
@@ -161,6 +162,8 @@ namespace DiscImageChef.Filesystems.ISO9660
entryOff += record.length; entryOff += record.length;
} }
if(useTransTbl) DecodeTransTable(entries);
return entries; return entries;
} }
@@ -274,12 +277,71 @@ namespace DiscImageChef.Filesystems.ISO9660
entryOff += record.length; entryOff += record.length;
} }
if(useTransTbl) DecodeTransTable(entries);
// Relocated directories should be shown in correct place when using Rock Ridge namespace // Relocated directories should be shown in correct place when using Rock Ridge namespace
return @namespace == Namespace.Rrip return @namespace == Namespace.Rrip
? entries.Where(e => !e.Value.RockRidgeRelocated).ToDictionary(x => x.Key, x => x.Value) ? entries.Where(e => !e.Value.RockRidgeRelocated).ToDictionary(x => x.Key, x => x.Value)
: entries; : entries;
} }
void DecodeTransTable(Dictionary<string, DecodedDirectoryEntry> entries)
{
KeyValuePair<string, DecodedDirectoryEntry> transTblEntry =
entries.FirstOrDefault(e => !e.Value.Flags.HasFlag(FileFlags.Directory) &&
(e.Value.Filename.ToLower(CultureInfo.CurrentUICulture) == "trans.tbl" ||
e.Value.Filename.ToLower(CultureInfo.CurrentUICulture) == "trans.tbl;1"));
if(transTblEntry.Value == null) return;
uint transTblSectors = transTblEntry.Value.Size / 2048;
if(transTblEntry.Value.Size % 2048 > 0) transTblSectors++;
byte[] transTbl = image.ReadSectors(transTblEntry.Value.Extent, transTblSectors);
MemoryStream mr = new MemoryStream(transTbl, 0, (int)transTblEntry.Value.Size, false);
StreamReader sr = new StreamReader(mr, Encoding);
string line = sr.ReadLine();
while(line != null)
{
// Skip the type field and the first space
string cutLine = line.Substring(2);
int spaceIndex = cutLine.IndexOf(' ');
string originalName = cutLine.Substring(0, spaceIndex);
string originalNameWithVersion;
string newName = cutLine.Substring(spaceIndex + 1);
if(originalName.EndsWith(";1", StringComparison.Ordinal))
{
originalNameWithVersion = originalName.ToLower(CultureInfo.CurrentUICulture);
originalName = originalNameWithVersion.Substring(0, originalName.Length - 2);
}
else
{
originalName = originalName.ToLower(CultureInfo.CurrentUICulture);
originalNameWithVersion = originalName + ";1";
}
// Pre-read next line
line = sr.ReadLine();
KeyValuePair<string, DecodedDirectoryEntry> originalEntry =
entries.FirstOrDefault(e => !e.Value.Flags.HasFlag(FileFlags.Directory) &&
(e.Value.Filename.ToLower(CultureInfo.CurrentUICulture) ==
originalName ||
e.Value.Filename.ToLower(CultureInfo.CurrentUICulture) ==
originalNameWithVersion));
originalEntry.Value.Filename = newName;
entries.Remove(originalEntry.Key);
entries[newName] = originalEntry.Value;
}
entries.Remove(transTblEntry.Key);
}
void DecodeSystemArea(byte[] data, int start, int end, ref DecodedDirectoryEntry entry, void DecodeSystemArea(byte[] data, int start, int end, ref DecodedDirectoryEntry entry,
out bool hasResourceFork) out bool hasResourceFork)
{ {

View File

@@ -53,6 +53,7 @@ namespace DiscImageChef.Filesystems.ISO9660
Dictionary<string, DecodedDirectoryEntry> rootDirectoryCache; Dictionary<string, DecodedDirectoryEntry> rootDirectoryCache;
FileSystemInfo statfs; FileSystemInfo statfs;
bool usePathTable; bool usePathTable;
bool useTransTbl;
public FileSystemType XmlFsType { get; private set; } public FileSystemType XmlFsType { get; private set; }
public Encoding Encoding { get; private set; } public Encoding Encoding { get; private set; }
@@ -63,7 +64,8 @@ namespace DiscImageChef.Filesystems.ISO9660
public IEnumerable<(string name, Type type, string description)> SupportedOptions => public IEnumerable<(string name, Type type, string description)> SupportedOptions =>
new (string name, Type type, string description)[] new (string name, Type type, string description)[]
{ {
("use_path_table", typeof(bool), "Use path table for directory traversal") ("use_path_table", typeof(bool), "Use path table for directory traversal"),
("use_trans_tbl", typeof(bool), "Use TRANS.TBL for filenames")
}; };
public Dictionary<string, string> Namespaces => public Dictionary<string, string> Namespaces =>

View File

@@ -24,6 +24,8 @@ namespace DiscImageChef.Filesystems.ISO9660
if(options.TryGetValue("debug", out string debugString)) bool.TryParse(debugString, out debug); if(options.TryGetValue("debug", out string debugString)) bool.TryParse(debugString, out debug);
if(options.TryGetValue("use_path_table", out string usePathTableString)) if(options.TryGetValue("use_path_table", out string usePathTableString))
bool.TryParse(usePathTableString, out usePathTable); bool.TryParse(usePathTableString, out usePathTable);
if(options.TryGetValue("use_trans_tbl", out string useTransTblString))
bool.TryParse(useTransTblString, out useTransTbl);
// Default namespace // Default namespace
if(@namespace is null) @namespace = "joliet"; if(@namespace is null) @namespace = "joliet";
@@ -252,7 +254,14 @@ namespace DiscImageChef.Filesystems.ISO9660
// TODO: Add IP.BIN to debug root directory // TODO: Add IP.BIN to debug root directory
// TODO: Add volume descriptors to debug root directory // TODO: Add volume descriptors to debug root directory
if(this.@namespace == Namespace.Joliet || this.@namespace == Namespace.Rrip) usePathTable = false; if(this.@namespace == Namespace.Joliet || this.@namespace == Namespace.Rrip)
{
usePathTable = false;
useTransTbl = false;
}
// Cannot traverse path table if we substitute the names for the ones in TRANS.TBL
if(useTransTbl) usePathTable = false;
if(this.@namespace != Namespace.Joliet) if(this.@namespace != Namespace.Joliet)
rootDirectoryCache = cdi rootDirectoryCache = cdi