Make some values in FileEntryInfo nullable to indicate the underlying filesystem cannot represent them.

This commit is contained in:
2019-04-22 23:06:47 +01:00
parent af4c798483
commit 421ce1574b
7 changed files with 117 additions and 125 deletions

View File

@@ -161,62 +161,60 @@ namespace DiscImageChef.CommonTypes.Structs
public long Blocks; public long Blocks;
/// <summary>File block size in bytes</summary> /// <summary>File block size in bytes</summary>
public long BlockSize; public long BlockSize;
/// <summary>If file points to a device, device number</summary> /// <summary>If file points to a device, device number. Null if the underlying filesystem does not support them.</summary>
public ulong DeviceNo; public ulong? DeviceNo;
/// <summary>POSIX group ID</summary> /// <summary>POSIX group ID. Null if the underlying filesystem does not support them.</summary>
public ulong GID; public ulong? GID;
/// <summary>inode number for this file (or other unique identifier for the volume)</summary>
/// <summary>inode number for this file</summary>
public ulong Inode; public ulong Inode;
/// <summary>File length in bytes</summary> /// <summary>File length in bytes</summary>
public long Length; public long Length;
/// <summary>Number of hard links pointing to this file</summary> /// <summary>Number of hard links pointing to this file (. and .. entries count as hard links)</summary>
public ulong Links; public ulong Links;
/// <summary>POSIX permissions/mode for this file</summary> /// <summary>POSIX permissions/mode for this file. Null if the underlying filesystem does not support them.</summary>
public uint Mode; public uint? Mode;
/// <summary>POSIX owner ID</summary> /// <summary>POSIX owner ID. Null if the underlying filesystem does not support them.</summary>
public ulong UID; public ulong? UID;
/// <summary>File creation date in UTC. Null if the underlying filesystem does not support them.</summary>
public DateTime? CreationTimeUtc { get; set; }
/// <summary>File last access date in UTC. Null if the underlying filesystem does not support them.</summary>
public DateTime? AccessTimeUtc { get; set; }
/// <summary>File attributes change date in UTC. Null if the underlying filesystem does not support them.</summary>
public DateTime? StatusChangeTimeUtc { get; set; }
/// <summary>File last backup date in UTC. Null if the underlying filesystem does not support them.</summary>
public DateTime? BackupTimeUtc { get; set; }
/// <summary>File last modification date in UTC. Null if the underlying filesystem does not support them.</summary>
public DateTime? LastWriteTimeUtc { get; set; }
/// <summary>File creation date in UTC</summary> /// <summary>File creation date. Null if the underlying filesystem does not support them.</summary>
public DateTime CreationTimeUtc { get; set; } public DateTime? CreationTime
/// <summary>File last access date in UTC</summary>
public DateTime AccessTimeUtc { get; set; }
/// <summary>File attributes change date in UTC</summary>
public DateTime StatusChangeTimeUtc { get; set; }
/// <summary>File last backup date in UTC</summary>
public DateTime BackupTimeUtc { get; set; }
/// <summary>File last modification date in UTC</summary>
public DateTime LastWriteTimeUtc { get; set; }
/// <summary>File creation date</summary>
public DateTime CreationTime
{ {
get => CreationTimeUtc.ToLocalTime(); get => CreationTimeUtc?.ToLocalTime();
set => CreationTimeUtc = value.ToUniversalTime(); set => CreationTimeUtc = value?.ToUniversalTime();
} }
/// <summary>File last access date</summary> /// <summary>File last access date. Null if the underlying filesystem does not support them.</summary>
public DateTime AccessTime public DateTime? AccessTime
{ {
get => AccessTimeUtc.ToLocalTime(); get => AccessTimeUtc?.ToLocalTime();
set => AccessTimeUtc = value.ToUniversalTime(); set => AccessTimeUtc = value?.ToUniversalTime();
} }
/// <summary>File attributes change date</summary> /// <summary>File attributes change date. Null if the underlying filesystem does not support them.</summary>
public DateTime StatusChangeTime public DateTime? StatusChangeTime
{ {
get => StatusChangeTimeUtc.ToLocalTime(); get => StatusChangeTimeUtc?.ToLocalTime();
set => StatusChangeTimeUtc = value.ToUniversalTime(); set => StatusChangeTimeUtc = value?.ToUniversalTime();
} }
/// <summary>File last backup date</summary> /// <summary>File last backup date. Null if the underlying filesystem does not support them.</summary>
public DateTime BackupTime public DateTime? BackupTime
{ {
get => BackupTimeUtc.ToLocalTime(); get => BackupTimeUtc?.ToLocalTime();
set => BackupTimeUtc = value.ToUniversalTime(); set => BackupTimeUtc = value?.ToUniversalTime();
} }
/// <summary>File last modification date</summary> /// <summary>File last modification date. Null if the underlying filesystem does not support them.</summary>
public DateTime LastWriteTime public DateTime? LastWriteTime
{ {
get => LastWriteTimeUtc.ToLocalTime(); get => LastWriteTimeUtc?.ToLocalTime();
set => LastWriteTimeUtc = value.ToUniversalTime(); set => LastWriteTimeUtc = value?.ToUniversalTime();
} }
} }
@@ -236,7 +234,6 @@ namespace DiscImageChef.CommonTypes.Structs
public FileSystemId Id; public FileSystemId Id;
/// <summary>ID of plugin for this file</summary> /// <summary>ID of plugin for this file</summary>
public Guid PluginId; public Guid PluginId;
/// <summary>Filesystem type</summary> /// <summary>Filesystem type</summary>
public string Type; public string Type;

View File

@@ -169,14 +169,7 @@ namespace DiscImageChef.Filesystems.AppleMFS
{ {
stat = new FileEntryInfo stat = new FileEntryInfo
{ {
BlockSize = device.Info.SectorSize, BlockSize = device.Info.SectorSize, Inode = 0, Links = 1, Attributes = FileAttributes.System
DeviceNo = 0,
GID = 0,
Inode = 0,
Links = 1,
Mode = 0x124,
UID = 0,
Attributes = FileAttributes.System
}; };
if(string.Compare(path, "$", StringComparison.InvariantCulture) == 0) if(string.Compare(path, "$", StringComparison.InvariantCulture) == 0)
@@ -217,14 +210,10 @@ namespace DiscImageChef.Filesystems.AppleMFS
Blocks = entry.flLgLen / volMDB.drAlBlkSiz, Blocks = entry.flLgLen / volMDB.drAlBlkSiz,
BlockSize = volMDB.drAlBlkSiz, BlockSize = volMDB.drAlBlkSiz,
CreationTime = DateHandlers.MacToDateTime(entry.flCrDat), CreationTime = DateHandlers.MacToDateTime(entry.flCrDat),
DeviceNo = 0,
GID = 0,
Inode = entry.flFlNum, Inode = entry.flFlNum,
LastWriteTime = DateHandlers.MacToDateTime(entry.flMdDat), LastWriteTime = DateHandlers.MacToDateTime(entry.flMdDat),
Length = entry.flPyLen, Length = entry.flPyLen,
Links = 1, Links = 1
Mode = 0x124,
UID = 0
}; };
return Errno.NoError; return Errno.NoError;
@@ -304,8 +293,7 @@ namespace DiscImageChef.Filesystems.AppleMFS
else else
{ {
if(resourceFork) if(resourceFork)
if(ms.Length < entry.flRLgLen) if(ms.Length < entry.flRLgLen) buf = ms.ToArray();
buf = ms.ToArray();
else else
{ {
buf = new byte[entry.flRLgLen]; buf = new byte[entry.flRLgLen];

View File

@@ -128,13 +128,9 @@ namespace DiscImageChef.Filesystems.FATX
Attributes = FileAttributes.Directory | FileAttributes.System | FileAttributes.Hidden, Attributes = FileAttributes.Directory | FileAttributes.System | FileAttributes.Hidden,
Blocks = GetClusters(superblock.rootDirectoryCluster).Length, Blocks = GetClusters(superblock.rootDirectoryCluster).Length,
BlockSize = bytesPerCluster, BlockSize = bytesPerCluster,
DeviceNo = 0,
GID = 0,
Length = GetClusters(superblock.rootDirectoryCluster).Length * bytesPerCluster, Length = GetClusters(superblock.rootDirectoryCluster).Length * bytesPerCluster,
Inode = superblock.rootDirectoryCluster, Inode = superblock.rootDirectoryCluster,
Links = 1, Links = 1
Mode = 0x16D,
UID = 0
}; };
return Errno.NoError; return Errno.NoError;
@@ -148,13 +144,9 @@ namespace DiscImageChef.Filesystems.FATX
Attributes = new FileAttributes(), Attributes = new FileAttributes(),
Blocks = entry.length / bytesPerCluster, Blocks = entry.length / bytesPerCluster,
BlockSize = bytesPerCluster, BlockSize = bytesPerCluster,
DeviceNo = 0,
GID = 0,
Length = entry.length, Length = entry.length,
Inode = entry.firstCluster, Inode = entry.firstCluster,
Links = 1, Links = 1,
Mode = (uint)(entry.attributes.HasFlag(Attributes.Directory) ? 0x16D : 0x124),
UID = 0,
CreationTime = CreationTime =
littleEndian littleEndian
? DateHandlers.DosToDateTime(entry.creationDate, entry.creationTime).AddYears(20) ? DateHandlers.DosToDateTime(entry.creationDate, entry.creationTime).AddYears(20)

View File

@@ -226,8 +226,7 @@ namespace DiscImageChef.Filesystems.LisaFS
ExtentFile file; ExtentFile file;
if(fileId <= 4) if(fileId <= 4)
if(!debug || fileId == 0) if(!debug || fileId == 0) return Errno.NoSuchFile;
return Errno.NoSuchFile;
else else
{ {
stat = new FileEntryInfo {Attributes = new FileAttributes()}; stat = new FileEntryInfo {Attributes = new FileAttributes()};
@@ -246,11 +245,7 @@ namespace DiscImageChef.Filesystems.LisaFS
stat.LastWriteTime = DateHandlers.LisaToDateTime(file.dtm); stat.LastWriteTime = DateHandlers.LisaToDateTime(file.dtm);
stat.Inode = (ulong)fileId; stat.Inode = (ulong)fileId;
stat.Mode = 0x124;
stat.Links = 0; stat.Links = 0;
stat.UID = 0;
stat.GID = 0;
stat.DeviceNo = 0;
stat.Length = mddf.datasize; stat.Length = mddf.datasize;
stat.BlockSize = mddf.datasize; stat.BlockSize = mddf.datasize;
stat.Blocks = 1; stat.Blocks = 1;
@@ -265,11 +260,7 @@ namespace DiscImageChef.Filesystems.LisaFS
stat.BackupTime = mddf.dtvb; stat.BackupTime = mddf.dtvb;
stat.Inode = (ulong)fileId; stat.Inode = (ulong)fileId;
stat.Mode = 0x124;
stat.Links = 0; stat.Links = 0;
stat.UID = 0;
stat.GID = 0;
stat.DeviceNo = 0;
stat.Length = buf.Length; stat.Length = buf.Length;
stat.BlockSize = mddf.datasize; stat.BlockSize = mddf.datasize;
stat.Blocks = buf.Length / mddf.datasize; stat.Blocks = buf.Length / mddf.datasize;
@@ -290,12 +281,8 @@ namespace DiscImageChef.Filesystems.LisaFS
stat.BackupTime = DateHandlers.LisaToDateTime(file.dtb); stat.BackupTime = DateHandlers.LisaToDateTime(file.dtb);
stat.LastWriteTime = DateHandlers.LisaToDateTime(file.dtm); stat.LastWriteTime = DateHandlers.LisaToDateTime(file.dtm);
stat.Inode = (ulong)fileId; stat.Inode = (ulong)fileId;
stat.Mode = 0x1B6; stat.Links = 1;
stat.Links = 1;
stat.UID = 0;
stat.GID = 0;
stat.DeviceNo = 0;
if(!fileSizeCache.TryGetValue(fileId, out int len)) stat.Length = srecords[fileId].filesize; if(!fileSizeCache.TryGetValue(fileId, out int len)) stat.Length = srecords[fileId].filesize;
else stat.Length = len; else stat.Length = len;
stat.BlockSize = mddf.datasize; stat.BlockSize = mddf.datasize;

View File

@@ -113,12 +113,7 @@ namespace DiscImageChef.Filesystems.UCSDPascal
{ {
Attributes = FileAttributes.System, Attributes = FileAttributes.System,
BlockSize = device.Info.SectorSize * multiplier, BlockSize = device.Info.SectorSize * multiplier,
DeviceNo = 0, Links = 1
GID = 0,
Inode = 0,
Links = 1,
Mode = 0x124,
UID = 0
}; };
if(string.Compare(path, "$", StringComparison.InvariantCulture) == 0) if(string.Compare(path, "$", StringComparison.InvariantCulture) == 0)
@@ -144,15 +139,10 @@ namespace DiscImageChef.Filesystems.UCSDPascal
Attributes = FileAttributes.File, Attributes = FileAttributes.File,
Blocks = entry.LastBlock - entry.FirstBlock, Blocks = entry.LastBlock - entry.FirstBlock,
BlockSize = device.Info.SectorSize * multiplier, BlockSize = device.Info.SectorSize * multiplier,
DeviceNo = 0,
GID = 0,
Inode = 0,
LastWriteTimeUtc = DateHandlers.UcsdPascalToDateTime(entry.ModificationTime), LastWriteTimeUtc = DateHandlers.UcsdPascalToDateTime(entry.ModificationTime),
Length = (entry.LastBlock - entry.FirstBlock) * device.Info.SectorSize * multiplier + Length = (entry.LastBlock - entry.FirstBlock) * device.Info.SectorSize * multiplier +
entry.LastBytes, entry.LastBytes,
Links = 1, Links = 1
Mode = 0x124,
UID = 0
}; };
return Errno.NoError; return Errno.NoError;

View File

@@ -49,15 +49,15 @@ namespace DiscImageChef.Gui.Panels
// TODO: Show xattrs // TODO: Show xattrs
public class pnlListFiles : Panel public class pnlListFiles : Panel
{ {
GridColumn accessColumn; readonly GridColumn accessColumn;
bool ascendingSort; bool ascendingSort;
GridColumn attributesColumn; readonly GridColumn attributesColumn;
GridColumn backupColumn; readonly GridColumn backupColumn;
GridColumn changedColumn; readonly GridColumn changedColumn;
GridColumn createdColumn; readonly GridColumn createdColumn;
ObservableCollection<EntryForGrid> entries; readonly ObservableCollection<EntryForGrid> entries;
IReadOnlyFilesystem filesystem; readonly IReadOnlyFilesystem filesystem;
GridColumn gidColumn; readonly GridColumn gidColumn;
#region XAML controls #region XAML controls
#pragma warning disable 169 #pragma warning disable 169
@@ -67,15 +67,15 @@ namespace DiscImageChef.Gui.Panels
#pragma warning restore 649 #pragma warning restore 649
#endregion #endregion
GridColumn inodeColumn; readonly GridColumn inodeColumn;
GridColumn linksColumn; readonly GridColumn linksColumn;
GridColumn modeColumn; readonly GridColumn modeColumn;
GridColumn nameColumn; readonly GridColumn nameColumn;
ButtonMenuItem saveFilesMenuItem; readonly ButtonMenuItem saveFilesMenuItem;
GridColumn sizeColumn; readonly GridColumn sizeColumn;
GridColumn sortedColumn; GridColumn sortedColumn;
GridColumn uidColumn; readonly GridColumn uidColumn;
GridColumn writeColumn; readonly GridColumn writeColumn;
public pnlListFiles(IReadOnlyFilesystem filesystem, Dictionary<string, FileEntryInfo> files, string parentPath) public pnlListFiles(IReadOnlyFilesystem filesystem, Dictionary<string, FileEntryInfo> files, string parentPath)
{ {
@@ -406,19 +406,28 @@ namespace DiscImageChef.Gui.Panels
fs.Close(); fs.Close();
FileInfo fi = new FileInfo(outputPath); FileInfo fi = new FileInfo(outputPath);
#pragma warning disable RECS0022 // A catch clause that catches System.Exception and has an empty body #pragma warning disable RECS0022 // A catch clause that catches System.Exception and has an empty body
try { fi.CreationTimeUtc = file.Stat.CreationTimeUtc; } try
{
if(file.Stat.CreationTimeUtc.HasValue) fi.CreationTimeUtc = file.Stat.CreationTimeUtc.Value;
}
catch catch
{ {
// ignored // ignored
} }
try { fi.LastWriteTimeUtc = file.Stat.LastWriteTimeUtc; } try
{
if(file.Stat.LastWriteTimeUtc.HasValue) fi.LastWriteTimeUtc = file.Stat.LastWriteTimeUtc.Value;
}
catch catch
{ {
// ignored // ignored
} }
try { fi.LastAccessTimeUtc = file.Stat.AccessTimeUtc; } try
{
if(file.Stat.AccessTimeUtc.HasValue) fi.LastAccessTimeUtc = file.Stat.AccessTimeUtc.Value;
}
catch catch
{ {
// ignored // ignored

View File

@@ -369,19 +369,28 @@ namespace DiscImageChef.Commands
DirectoryInfo di = new DirectoryInfo(outputPath); DirectoryInfo di = new DirectoryInfo(outputPath);
#pragma warning disable RECS0022 // A catch clause that catches System.Exception and has an empty body #pragma warning disable RECS0022 // A catch clause that catches System.Exception and has an empty body
try { di.CreationTimeUtc = stat.CreationTimeUtc; } try
{
if(stat.CreationTimeUtc.HasValue) di.CreationTimeUtc = stat.CreationTimeUtc.Value;
}
catch catch
{ {
// ignored // ignored
} }
try { di.LastWriteTimeUtc = stat.LastWriteTimeUtc; } try
{
if(stat.LastWriteTimeUtc.HasValue) di.LastWriteTimeUtc = stat.LastWriteTimeUtc.Value;
}
catch catch
{ {
// ignored // ignored
} }
try { di.LastAccessTimeUtc = stat.AccessTimeUtc; } try
{
if(stat.AccessTimeUtc.HasValue) di.LastAccessTimeUtc = stat.AccessTimeUtc.Value;
}
catch catch
{ {
// ignored // ignored
@@ -416,19 +425,30 @@ namespace DiscImageChef.Commands
outputFile.Close(); outputFile.Close();
FileInfo fi = new FileInfo(outputPath); FileInfo fi = new FileInfo(outputPath);
#pragma warning disable RECS0022 // A catch clause that catches System.Exception and has an empty body #pragma warning disable RECS0022 // A catch clause that catches System.Exception and has an empty body
try { fi.CreationTimeUtc = stat.CreationTimeUtc; } try
{
if(stat.CreationTimeUtc.HasValue)
fi.CreationTimeUtc = stat.CreationTimeUtc.Value;
}
catch catch
{ {
// ignored // ignored
} }
try { fi.LastWriteTimeUtc = stat.LastWriteTimeUtc; } try
{
if(stat.LastWriteTimeUtc.HasValue)
fi.LastWriteTimeUtc = stat.LastWriteTimeUtc.Value;
}
catch catch
{ {
// ignored // ignored
} }
try { fi.LastAccessTimeUtc = stat.AccessTimeUtc; } try
{
if(stat.AccessTimeUtc.HasValue) fi.LastAccessTimeUtc = stat.AccessTimeUtc.Value;
}
catch catch
{ {
// ignored // ignored
@@ -461,19 +481,28 @@ namespace DiscImageChef.Commands
outputFile.Close(); outputFile.Close();
FileInfo fi = new FileInfo(outputPath); FileInfo fi = new FileInfo(outputPath);
#pragma warning disable RECS0022 // A catch clause that catches System.Exception and has an empty body #pragma warning disable RECS0022 // A catch clause that catches System.Exception and has an empty body
try { fi.CreationTimeUtc = stat.CreationTimeUtc; } try
{
if(stat.CreationTimeUtc.HasValue) fi.CreationTimeUtc = stat.CreationTimeUtc.Value;
}
catch catch
{ {
// ignored // ignored
} }
try { fi.LastWriteTimeUtc = stat.LastWriteTimeUtc; } try
{
if(stat.LastWriteTimeUtc.HasValue) fi.LastWriteTimeUtc = stat.LastWriteTimeUtc.Value;
}
catch catch
{ {
// ignored // ignored
} }
try { fi.LastAccessTimeUtc = stat.AccessTimeUtc; } try
{
if(stat.AccessTimeUtc.HasValue) fi.LastAccessTimeUtc = stat.AccessTimeUtc.Value;
}
catch catch
{ {
// ignored // ignored