mirror of
https://github.com/aaru-dps/Aaru.Server.git
synced 2025-12-16 19:24:27 +00:00
Refactor AppleDOS and solves bug preventing VTOC from being retrieved as "$Vtoc".
This commit is contained in:
@@ -47,9 +47,7 @@ namespace DiscImageChef.Filesystems.AppleDOS
|
|||||||
/// <param name="dest">Link destination.</param>
|
/// <param name="dest">Link destination.</param>
|
||||||
public override Errno ReadLink(string path, ref string dest)
|
public override Errno ReadLink(string path, ref string dest)
|
||||||
{
|
{
|
||||||
if(!mounted) return Errno.AccessDenied;
|
return !mounted ? Errno.AccessDenied : Errno.NotSupported;
|
||||||
|
|
||||||
return Errno.NotSupported;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -97,10 +95,9 @@ namespace DiscImageChef.Filesystems.AppleDOS
|
|||||||
if(debug) catalogMs.Write(catSectorB, 0, catSectorB.Length);
|
if(debug) catalogMs.Write(catSectorB, 0, catSectorB.Length);
|
||||||
|
|
||||||
// Read the catalog sector
|
// Read the catalog sector
|
||||||
CatalogSector catSector;
|
|
||||||
IntPtr catPtr = Marshal.AllocHGlobal(256);
|
IntPtr catPtr = Marshal.AllocHGlobal(256);
|
||||||
Marshal.Copy(catSectorB, 0, catPtr, 256);
|
Marshal.Copy(catSectorB, 0, catPtr, 256);
|
||||||
catSector = (CatalogSector)Marshal.PtrToStructure(catPtr, typeof(CatalogSector));
|
CatalogSector catSector = (CatalogSector)Marshal.PtrToStructure(catPtr, typeof(CatalogSector));
|
||||||
Marshal.FreeHGlobal(catPtr);
|
Marshal.FreeHGlobal(catPtr);
|
||||||
|
|
||||||
foreach(FileEntry entry in catSector.entries.Where(entry => entry.extentTrack > 0)) {
|
foreach(FileEntry entry in catSector.entries.Where(entry => entry.extentTrack > 0)) {
|
||||||
|
|||||||
@@ -33,6 +33,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace DiscImageChef.Filesystems.AppleDOS
|
namespace DiscImageChef.Filesystems.AppleDOS
|
||||||
@@ -70,7 +71,6 @@ namespace DiscImageChef.Filesystems.AppleDOS
|
|||||||
if(pathElements.Length != 1) return Errno.NotSupported;
|
if(pathElements.Length != 1) return Errno.NotSupported;
|
||||||
|
|
||||||
byte[] file;
|
byte[] file;
|
||||||
Errno error;
|
|
||||||
string filename = pathElements[0].ToUpperInvariant();
|
string filename = pathElements[0].ToUpperInvariant();
|
||||||
if(filename.Length > 30) return Errno.NameTooLong;
|
if(filename.Length > 30) return Errno.NameTooLong;
|
||||||
|
|
||||||
@@ -78,15 +78,18 @@ namespace DiscImageChef.Filesystems.AppleDOS
|
|||||||
string.Compare(path, "$Boot", StringComparison.InvariantCulture) == 0 ||
|
string.Compare(path, "$Boot", StringComparison.InvariantCulture) == 0 ||
|
||||||
string.Compare(path, "$Vtoc", StringComparison.InvariantCulture) == 0))
|
string.Compare(path, "$Vtoc", StringComparison.InvariantCulture) == 0))
|
||||||
{
|
{
|
||||||
if(string.Compare(path, "$", StringComparison.InvariantCulture) == 0) file = catalogBlocks;
|
if(string.Compare(path, "$", StringComparison.InvariantCulture) == 0)
|
||||||
if(string.Compare(path, "$Vtoc", StringComparison.InvariantCulture) == 0) file = vtocBlocks;
|
file = catalogBlocks;
|
||||||
else file = bootBlocks;
|
else if(string.Compare(path, "$Vtoc", StringComparison.InvariantCulture) == 0)
|
||||||
|
file = vtocBlocks;
|
||||||
|
else
|
||||||
|
file = bootBlocks;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(!fileCache.TryGetValue(filename, out file))
|
if(!fileCache.TryGetValue(filename, out file))
|
||||||
{
|
{
|
||||||
error = CacheFile(filename);
|
Errno error = CacheFile(filename);
|
||||||
if(error != Errno.NoError) return error;
|
if(error != Errno.NoError) return error;
|
||||||
|
|
||||||
if(!fileCache.TryGetValue(filename, out file)) return Errno.InvalidArgument;
|
if(!fileCache.TryGetValue(filename, out file)) return Errno.InvalidArgument;
|
||||||
@@ -116,10 +119,9 @@ namespace DiscImageChef.Filesystems.AppleDOS
|
|||||||
|
|
||||||
if(!fileCache.ContainsKey(filename)) return Errno.NoSuchFile;
|
if(!fileCache.ContainsKey(filename)) return Errno.NoSuchFile;
|
||||||
|
|
||||||
int filesize;
|
|
||||||
FileAttributes attrs = new FileAttributes();
|
FileAttributes attrs = new FileAttributes();
|
||||||
|
|
||||||
fileSizeCache.TryGetValue(filename, out filesize);
|
fileSizeCache.TryGetValue(filename, out int filesize);
|
||||||
GetAttributes(path, ref attrs);
|
GetAttributes(path, ref attrs);
|
||||||
|
|
||||||
stat = new FileEntryInfo();
|
stat = new FileEntryInfo();
|
||||||
@@ -152,10 +154,8 @@ namespace DiscImageChef.Filesystems.AppleDOS
|
|||||||
|
|
||||||
public override Errno MapBlock(string path, long fileBlock, ref long deviceBlock)
|
public override Errno MapBlock(string path, long fileBlock, ref long deviceBlock)
|
||||||
{
|
{
|
||||||
if(!mounted) return Errno.AccessDenied;
|
|
||||||
|
|
||||||
// TODO: Not really important.
|
// TODO: Not really important.
|
||||||
return Errno.NotImplemented;
|
return !mounted ? Errno.AccessDenied : Errno.NotImplemented;
|
||||||
}
|
}
|
||||||
|
|
||||||
Errno CacheFile(string path)
|
Errno CacheFile(string path)
|
||||||
@@ -166,9 +166,7 @@ namespace DiscImageChef.Filesystems.AppleDOS
|
|||||||
string filename = pathElements[0].ToUpperInvariant();
|
string filename = pathElements[0].ToUpperInvariant();
|
||||||
if(filename.Length > 30) return Errno.NameTooLong;
|
if(filename.Length > 30) return Errno.NameTooLong;
|
||||||
|
|
||||||
ushort ts;
|
if(!catalogCache.TryGetValue(filename, out ushort ts)) return Errno.NoSuchFile;
|
||||||
|
|
||||||
if(!catalogCache.TryGetValue(filename, out ts)) return Errno.NoSuchFile;
|
|
||||||
|
|
||||||
ulong lba = (ulong)(((ts & 0xFF00) >> 8) * sectorsPerTrack + (ts & 0xFF));
|
ulong lba = (ulong)(((ts & 0xFF00) >> 8) * sectorsPerTrack + (ts & 0xFF));
|
||||||
MemoryStream fileMs = new MemoryStream();
|
MemoryStream fileMs = new MemoryStream();
|
||||||
@@ -182,10 +180,9 @@ namespace DiscImageChef.Filesystems.AppleDOS
|
|||||||
if(debug) tsListMs.Write(tsSectorB, 0, tsSectorB.Length);
|
if(debug) tsListMs.Write(tsSectorB, 0, tsSectorB.Length);
|
||||||
|
|
||||||
// Read the track/sector list sector
|
// Read the track/sector list sector
|
||||||
TrackSectorList tsSector;
|
|
||||||
IntPtr tsPtr = Marshal.AllocHGlobal(256);
|
IntPtr tsPtr = Marshal.AllocHGlobal(256);
|
||||||
Marshal.Copy(tsSectorB, 0, tsPtr, 256);
|
Marshal.Copy(tsSectorB, 0, tsPtr, 256);
|
||||||
tsSector = (TrackSectorList)Marshal.PtrToStructure(tsPtr, typeof(TrackSectorList));
|
TrackSectorList tsSector = (TrackSectorList)Marshal.PtrToStructure(tsPtr, typeof(TrackSectorList));
|
||||||
Marshal.FreeHGlobal(tsPtr);
|
Marshal.FreeHGlobal(tsPtr);
|
||||||
|
|
||||||
if(tsSector.sectorOffset > expectedBlock)
|
if(tsSector.sectorOffset > expectedBlock)
|
||||||
@@ -225,13 +222,9 @@ namespace DiscImageChef.Filesystems.AppleDOS
|
|||||||
{
|
{
|
||||||
fileCache = new Dictionary<string, byte[]>();
|
fileCache = new Dictionary<string, byte[]>();
|
||||||
extentCache = new Dictionary<string, byte[]>();
|
extentCache = new Dictionary<string, byte[]>();
|
||||||
Errno error;
|
|
||||||
|
|
||||||
foreach(string file in catalogCache.Keys)
|
foreach(Errno error in catalogCache.Keys.Select(CacheFile).Where(error => error != Errno.NoError))
|
||||||
{
|
{ return error; }
|
||||||
error = CacheFile(file);
|
|
||||||
if(error != Errno.NoError) return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint tracksOnBoot = 1;
|
uint tracksOnBoot = 1;
|
||||||
if(!track1UsedByFiles) tracksOnBoot++;
|
if(!track1UsedByFiles) tracksOnBoot++;
|
||||||
|
|||||||
@@ -48,8 +48,7 @@ namespace DiscImageChef.Filesystems.AppleDOS
|
|||||||
if(partition.Start > 0 || imagePlugin.ImageInfo.SectorSize != 256) return false;
|
if(partition.Start > 0 || imagePlugin.ImageInfo.SectorSize != 256) return false;
|
||||||
|
|
||||||
int spt;
|
int spt;
|
||||||
if(imagePlugin.ImageInfo.Sectors == 455) spt = 13;
|
spt = imagePlugin.ImageInfo.Sectors == 455 ? 13 : 16;
|
||||||
else spt = 16;
|
|
||||||
|
|
||||||
byte[] vtocB = imagePlugin.ReadSector((ulong)(17 * spt));
|
byte[] vtocB = imagePlugin.ReadSector((ulong)(17 * spt));
|
||||||
vtoc = new Vtoc();
|
vtoc = new Vtoc();
|
||||||
@@ -68,8 +67,7 @@ namespace DiscImageChef.Filesystems.AppleDOS
|
|||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
|
|
||||||
int spt;
|
int spt;
|
||||||
if(imagePlugin.ImageInfo.Sectors == 455) spt = 13;
|
spt = imagePlugin.ImageInfo.Sectors == 455 ? 13 : 16;
|
||||||
else spt = 16;
|
|
||||||
|
|
||||||
byte[] vtocB = imagePlugin.ReadSector((ulong)(17 * spt));
|
byte[] vtocB = imagePlugin.ReadSector((ulong)(17 * spt));
|
||||||
vtoc = new Vtoc();
|
vtoc = new Vtoc();
|
||||||
@@ -93,11 +91,13 @@ namespace DiscImageChef.Filesystems.AppleDOS
|
|||||||
|
|
||||||
information = sb.ToString();
|
information = sb.ToString();
|
||||||
|
|
||||||
xmlFSType = new FileSystemType();
|
xmlFSType = new FileSystemType
|
||||||
xmlFSType.Bootable = true;
|
{
|
||||||
xmlFSType.Clusters = (long)imagePlugin.ImageInfo.Sectors;
|
Bootable = true,
|
||||||
xmlFSType.ClusterSize = (int)imagePlugin.ImageInfo.SectorSize;
|
Clusters = (long)imagePlugin.ImageInfo.Sectors,
|
||||||
xmlFSType.Type = "Apple DOS";
|
ClusterSize = (int)imagePlugin.ImageInfo.SectorSize,
|
||||||
|
Type = "Apple DOS"
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -70,14 +70,13 @@ namespace DiscImageChef.Filesystems.AppleDOS
|
|||||||
return Errno.InOutError;
|
return Errno.InOutError;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(device.ImageInfo.Sectors == 455) sectorsPerTrack = 13;
|
sectorsPerTrack = device.ImageInfo.Sectors == 455 ? 13 : 16;
|
||||||
else sectorsPerTrack = 16;
|
|
||||||
|
|
||||||
// Read the VTOC
|
// Read the VTOC
|
||||||
byte[] vtocB = device.ReadSector((ulong)(17 * sectorsPerTrack));
|
vtocBlocks = device.ReadSector((ulong)(17 * sectorsPerTrack));
|
||||||
vtoc = new Vtoc();
|
vtoc = new Vtoc();
|
||||||
IntPtr vtocPtr = Marshal.AllocHGlobal(256);
|
IntPtr vtocPtr = Marshal.AllocHGlobal(256);
|
||||||
Marshal.Copy(vtocB, 0, vtocPtr, 256);
|
Marshal.Copy(vtocBlocks, 0, vtocPtr, 256);
|
||||||
vtoc = (Vtoc)Marshal.PtrToStructure(vtocPtr, typeof(Vtoc));
|
vtoc = (Vtoc)Marshal.PtrToStructure(vtocPtr, typeof(Vtoc));
|
||||||
Marshal.FreeHGlobal(vtocPtr);
|
Marshal.FreeHGlobal(vtocPtr);
|
||||||
|
|
||||||
@@ -85,9 +84,7 @@ namespace DiscImageChef.Filesystems.AppleDOS
|
|||||||
track2UsedByFiles = false;
|
track2UsedByFiles = false;
|
||||||
usedSectors = 1;
|
usedSectors = 1;
|
||||||
|
|
||||||
Errno error;
|
Errno error = ReadCatalog();
|
||||||
|
|
||||||
error = ReadCatalog();
|
|
||||||
if(error != Errno.NoError)
|
if(error != Errno.NoError)
|
||||||
{
|
{
|
||||||
DicConsole.DebugWriteLine("Apple DOS plugin", "Unable to read catalog.");
|
DicConsole.DebugWriteLine("Apple DOS plugin", "Unable to read catalog.");
|
||||||
@@ -102,15 +99,17 @@ namespace DiscImageChef.Filesystems.AppleDOS
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create XML metadata for mounted filesystem
|
// Create XML metadata for mounted filesystem
|
||||||
xmlFSType = new FileSystemType();
|
xmlFSType = new FileSystemType
|
||||||
xmlFSType.Bootable = true;
|
{
|
||||||
xmlFSType.Clusters = (long)device.ImageInfo.Sectors;
|
Bootable = true,
|
||||||
xmlFSType.ClusterSize = vtoc.bytesPerSector;
|
Clusters = (long)device.ImageInfo.Sectors,
|
||||||
xmlFSType.Files = catalogCache.Count;
|
ClusterSize = vtoc.bytesPerSector,
|
||||||
xmlFSType.FilesSpecified = true;
|
Files = catalogCache.Count,
|
||||||
|
FilesSpecified = true,
|
||||||
|
FreeClustersSpecified = true,
|
||||||
|
Type = "Apple DOS"
|
||||||
|
};
|
||||||
xmlFSType.FreeClusters = xmlFSType.Clusters - usedSectors;
|
xmlFSType.FreeClusters = xmlFSType.Clusters - usedSectors;
|
||||||
xmlFSType.FreeClustersSpecified = true;
|
|
||||||
xmlFSType.Type = "Apple DOS";
|
|
||||||
|
|
||||||
this.debug = debug;
|
this.debug = debug;
|
||||||
mounted = true;
|
mounted = true;
|
||||||
@@ -137,14 +136,16 @@ namespace DiscImageChef.Filesystems.AppleDOS
|
|||||||
/// <param name="stat">Information about the mounted volume.</param>
|
/// <param name="stat">Information about the mounted volume.</param>
|
||||||
public override Errno StatFs(ref FileSystemInfo stat)
|
public override Errno StatFs(ref FileSystemInfo stat)
|
||||||
{
|
{
|
||||||
stat = new FileSystemInfo();
|
stat = new FileSystemInfo
|
||||||
stat.Blocks = (long)device.ImageInfo.Sectors;
|
{
|
||||||
stat.FilenameLength = 30;
|
Blocks = (long)device.ImageInfo.Sectors,
|
||||||
stat.Files = (ulong)catalogCache.Count;
|
FilenameLength = 30,
|
||||||
stat.FreeBlocks = stat.Blocks - usedSectors;
|
Files = (ulong)catalogCache.Count,
|
||||||
|
PluginId = PluginUUID,
|
||||||
|
Type = "Apple DOS"
|
||||||
|
};
|
||||||
stat.FreeFiles = totalFileEntries - stat.Files;
|
stat.FreeFiles = totalFileEntries - stat.Files;
|
||||||
stat.PluginId = PluginUUID;
|
stat.FreeBlocks = stat.Blocks - usedSectors;
|
||||||
stat.Type = "Apple DOS";
|
|
||||||
|
|
||||||
return Errno.NoError;
|
return Errno.NoError;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -95,8 +95,7 @@ namespace DiscImageChef.Filesystems.AppleDOS
|
|||||||
|
|
||||||
if(string.Compare(xattr, "com.apple.dos.type", StringComparison.InvariantCulture) == 0)
|
if(string.Compare(xattr, "com.apple.dos.type", StringComparison.InvariantCulture) == 0)
|
||||||
{
|
{
|
||||||
byte type;
|
if(!fileTypeCache.TryGetValue(filename, out byte type)) return Errno.InvalidArgument;
|
||||||
if(!fileTypeCache.TryGetValue(filename, out type)) return Errno.InvalidArgument;
|
|
||||||
|
|
||||||
buf = new byte[1];
|
buf = new byte[1];
|
||||||
buf[0] = type;
|
buf[0] = type;
|
||||||
@@ -106,8 +105,7 @@ namespace DiscImageChef.Filesystems.AppleDOS
|
|||||||
if(string.Compare(xattr, "com.apple.dos.tracksectorlist", StringComparison.InvariantCulture) != 0 || !debug)
|
if(string.Compare(xattr, "com.apple.dos.tracksectorlist", StringComparison.InvariantCulture) != 0 || !debug)
|
||||||
return Errno.NoSuchExtendedAttribute;
|
return Errno.NoSuchExtendedAttribute;
|
||||||
|
|
||||||
byte[] ts;
|
if(!extentCache.TryGetValue(filename, out byte[] ts)) return Errno.InvalidArgument;
|
||||||
if(!extentCache.TryGetValue(filename, out ts)) return Errno.InvalidArgument;
|
|
||||||
|
|
||||||
buf = new byte[ts.Length];
|
buf = new byte[ts.Length];
|
||||||
Array.Copy(ts, 0, buf, 0, buf.Length);
|
Array.Copy(ts, 0, buf, 0, buf.Length);
|
||||||
|
|||||||
Reference in New Issue
Block a user