mirror of
https://github.com/aaru-dps/Aaru.git
synced 2025-12-16 19:24:25 +00:00
Adds support for Apple DOS filesystem, closes #33.
This commit is contained in:
41
DiscImageChef.DiscImages/AppleNIB.cs
Normal file
41
DiscImageChef.DiscImages/AppleNIB.cs
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
// /***************************************************************************
|
||||||
|
// The Disc Image Chef
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Filename : AppleNIB.cs
|
||||||
|
// Author(s) : Natalia Portillo <claunia@claunia.com>
|
||||||
|
//
|
||||||
|
// Component : Component
|
||||||
|
//
|
||||||
|
// --[ Description ] ----------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Description
|
||||||
|
//
|
||||||
|
// --[ License ] --------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// This library is free software; you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Lesser General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2.1 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This library is distributed in the hope that it will be useful, but
|
||||||
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public
|
||||||
|
// License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// Copyright © 2011-2016 Natalia Portillo
|
||||||
|
// ****************************************************************************/
|
||||||
|
using System;
|
||||||
|
namespace DiscImageChef.DiscImages
|
||||||
|
{
|
||||||
|
public class AppleNIB
|
||||||
|
{
|
||||||
|
public AppleNIB()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
88
DiscImageChef.Filesystems/AppleDOS/AppleDOS.cs
Normal file
88
DiscImageChef.Filesystems/AppleDOS/AppleDOS.cs
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
// /***************************************************************************
|
||||||
|
// The Disc Image Chef
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Filename : AppleDOS.cs
|
||||||
|
// Author(s) : Natalia Portillo <claunia@claunia.com>
|
||||||
|
//
|
||||||
|
// Component : Apple DOS filesystem plugin.
|
||||||
|
//
|
||||||
|
// --[ Description ] ----------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Constructors and common variables for the Apple DOS filesystem plugin.
|
||||||
|
//
|
||||||
|
// --[ License ] --------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// This library is free software; you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Lesser General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2.1 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This library is distributed in the hope that it will be useful, but
|
||||||
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public
|
||||||
|
// License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// Copyright © 2011-2016 Natalia Portillo
|
||||||
|
// ****************************************************************************/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using DiscImageChef.ImagePlugins;
|
||||||
|
|
||||||
|
namespace DiscImageChef.Filesystems.AppleDOS
|
||||||
|
{
|
||||||
|
partial class AppleDOS : Filesystem
|
||||||
|
{
|
||||||
|
bool mounted;
|
||||||
|
bool debug;
|
||||||
|
readonly ImagePlugin device;
|
||||||
|
|
||||||
|
#region Caches
|
||||||
|
/// <summary>Caches track/sector lists</summary>
|
||||||
|
Dictionary<string, byte[]> extentCache;
|
||||||
|
/// <summary>Caches files</summary>
|
||||||
|
Dictionary<string, byte[]> fileCache;
|
||||||
|
/// <summary>Caches catalog</summary>
|
||||||
|
Dictionary<string, ushort> catalogCache;
|
||||||
|
/// <summary>Caches file size</summary>
|
||||||
|
Dictionary<string, int> fileSizeCache;
|
||||||
|
/// <summary>Caches VTOC</summary>
|
||||||
|
byte[] vtocBlocks;
|
||||||
|
/// <summary>Caches catalog</summary>
|
||||||
|
byte[] catalogBlocks;
|
||||||
|
/// <summary>Caches boot code</summary>
|
||||||
|
byte[] bootBlocks;
|
||||||
|
/// <summary>Caches file type</summary>
|
||||||
|
Dictionary<string, byte> fileTypeCache;
|
||||||
|
/// <summary>Caches locked files</summary>
|
||||||
|
List<string> lockedFiles;
|
||||||
|
#endregion Caches
|
||||||
|
|
||||||
|
VTOC vtoc;
|
||||||
|
ulong start;
|
||||||
|
int sectorsPerTrack;
|
||||||
|
ulong totalFileEntries;
|
||||||
|
bool track1UsedByFiles;
|
||||||
|
bool track2UsedByFiles;
|
||||||
|
int usedSectors;
|
||||||
|
|
||||||
|
public AppleDOS()
|
||||||
|
{
|
||||||
|
Name = "Apple DOS File System";
|
||||||
|
PluginUUID = new Guid("8658A1E9-B2E7-4BCC-9638-157A31B0A700\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
public AppleDOS(ImagePlugin imagePlugin, ulong partitionStart, ulong partitionEnd)
|
||||||
|
{
|
||||||
|
device = imagePlugin;
|
||||||
|
start = partitionStart;
|
||||||
|
Name = "Apple DOS File System";
|
||||||
|
PluginUUID = new Guid("8658A1E9-B2E7-4BCC-9638-157A31B0A700\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
153
DiscImageChef.Filesystems/AppleDOS/Dir.cs
Normal file
153
DiscImageChef.Filesystems/AppleDOS/Dir.cs
Normal file
@@ -0,0 +1,153 @@
|
|||||||
|
// /***************************************************************************
|
||||||
|
// The Disc Image Chef
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Filename : Dir.cs
|
||||||
|
// Author(s) : Natalia Portillo <claunia@claunia.com>
|
||||||
|
//
|
||||||
|
// Component : Apple DOS filesystem plugin.
|
||||||
|
//
|
||||||
|
// --[ Description ] ----------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Methods to handle Apple DOS filesystem catalog (aka directory).
|
||||||
|
//
|
||||||
|
// --[ License ] --------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// This library is free software; you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Lesser General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2.1 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This library is distributed in the hope that it will be useful, but
|
||||||
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public
|
||||||
|
// License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// Copyright © 2011-2016 Natalia Portillo
|
||||||
|
// ****************************************************************************/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace DiscImageChef.Filesystems.AppleDOS
|
||||||
|
{
|
||||||
|
partial class AppleDOS : Filesystem
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Solves a symbolic link.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="path">Link path.</param>
|
||||||
|
/// <param name="dest">Link destination.</param>
|
||||||
|
public override Errno ReadLink(string path, ref string dest)
|
||||||
|
{
|
||||||
|
if(!mounted)
|
||||||
|
return Errno.AccessDenied;
|
||||||
|
|
||||||
|
return Errno.NotSupported;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Lists contents from a directory.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="path">Directory path.</param>
|
||||||
|
/// <param name="contents">Directory contents.</param>
|
||||||
|
public override Errno ReadDir(string path, ref List<string> contents)
|
||||||
|
{
|
||||||
|
if(!mounted)
|
||||||
|
return Errno.AccessDenied;
|
||||||
|
|
||||||
|
if(!string.IsNullOrEmpty(path) && string.Compare(path, "/", StringComparison.OrdinalIgnoreCase) != 0)
|
||||||
|
return Errno.NotSupported;
|
||||||
|
|
||||||
|
contents = new List<string>();
|
||||||
|
foreach(string ent in catalogCache.Keys)
|
||||||
|
contents.Add(ent);
|
||||||
|
|
||||||
|
if(debug)
|
||||||
|
{
|
||||||
|
contents.Add("$");
|
||||||
|
contents.Add("$Boot");
|
||||||
|
contents.Add("$Vtoc");
|
||||||
|
}
|
||||||
|
|
||||||
|
contents.Sort();
|
||||||
|
return Errno.NoError;
|
||||||
|
}
|
||||||
|
|
||||||
|
Errno ReadCatalog()
|
||||||
|
{
|
||||||
|
MemoryStream catalogMs = new MemoryStream();
|
||||||
|
ulong lba = (ulong)((vtoc.catalogTrack * sectorsPerTrack) + vtoc.catalogSector);
|
||||||
|
totalFileEntries = 0;
|
||||||
|
catalogCache = new Dictionary<string, ushort>();
|
||||||
|
fileTypeCache = new Dictionary<string, byte>();
|
||||||
|
fileSizeCache = new Dictionary<string, int>();
|
||||||
|
lockedFiles = new List<string>();
|
||||||
|
|
||||||
|
if(lba == 0 || lba > device.ImageInfo.sectors)
|
||||||
|
return Errno.InvalidArgument;
|
||||||
|
|
||||||
|
while(lba != 0)
|
||||||
|
{
|
||||||
|
usedSectors++;
|
||||||
|
byte[] catSector_b = device.ReadSector(lba);
|
||||||
|
totalFileEntries += 7;
|
||||||
|
if(debug)
|
||||||
|
catalogMs.Write(catSector_b, 0, catSector_b.Length);
|
||||||
|
|
||||||
|
// Read the catalog sector
|
||||||
|
CatalogSector catSector = new CatalogSector();
|
||||||
|
IntPtr catPtr = Marshal.AllocHGlobal(256);
|
||||||
|
Marshal.Copy(catSector_b, 0, catPtr, 256);
|
||||||
|
catSector = (CatalogSector)Marshal.PtrToStructure(catPtr, typeof(CatalogSector));
|
||||||
|
Marshal.FreeHGlobal(catPtr);
|
||||||
|
|
||||||
|
foreach(FileEntry entry in catSector.entries)
|
||||||
|
{
|
||||||
|
if(entry.extentTrack > 0)
|
||||||
|
{
|
||||||
|
track1UsedByFiles |= entry.extentTrack == 1;
|
||||||
|
track2UsedByFiles |= entry.extentTrack == 2;
|
||||||
|
|
||||||
|
byte[] filename_b = new byte[30];
|
||||||
|
ushort ts = (ushort)((entry.extentTrack << 8) | entry.extentSector);
|
||||||
|
|
||||||
|
// Apple DOS has high byte set over ASCII.
|
||||||
|
for(int i = 0; i < 30; i++)
|
||||||
|
filename_b[i] = (byte)(entry.filename[i] & 0x7F);
|
||||||
|
|
||||||
|
string filename = StringHandlers.SpacePaddedToString(filename_b);
|
||||||
|
|
||||||
|
if(!catalogCache.ContainsKey(filename))
|
||||||
|
catalogCache.Add(filename, ts);
|
||||||
|
|
||||||
|
if(!fileTypeCache.ContainsKey(filename))
|
||||||
|
fileTypeCache.Add(filename, (byte)(entry.typeAndFlags & 0x7F));
|
||||||
|
|
||||||
|
if(!fileSizeCache.ContainsKey(filename))
|
||||||
|
fileSizeCache.Add(filename, entry.length * vtoc.bytesPerSector);
|
||||||
|
|
||||||
|
if((entry.typeAndFlags & 0x80) == 0x80 && !lockedFiles.Contains(filename))
|
||||||
|
lockedFiles.Add(filename);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lba = (ulong)((catSector.trackOfNext * sectorsPerTrack) + catSector.sectorOfNext);
|
||||||
|
|
||||||
|
if(lba > device.ImageInfo.sectors)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(debug)
|
||||||
|
catalogBlocks = catalogMs.ToArray();
|
||||||
|
|
||||||
|
return Errno.NoError;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
281
DiscImageChef.Filesystems/AppleDOS/File.cs
Normal file
281
DiscImageChef.Filesystems/AppleDOS/File.cs
Normal file
@@ -0,0 +1,281 @@
|
|||||||
|
// /***************************************************************************
|
||||||
|
// The Disc Image Chef
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Filename : File.cs
|
||||||
|
// Author(s) : Natalia Portillo <claunia@claunia.com>
|
||||||
|
//
|
||||||
|
// Component : Apple DOS filesystem plugin.
|
||||||
|
//
|
||||||
|
// --[ Description ] ----------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Methods to handle files.
|
||||||
|
//
|
||||||
|
// --[ License ] --------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// This library is free software; you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Lesser General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2.1 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This library is distributed in the hope that it will be useful, but
|
||||||
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public
|
||||||
|
// License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// Copyright © 2011-2016 Natalia Portillo
|
||||||
|
// ****************************************************************************/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace DiscImageChef.Filesystems.AppleDOS
|
||||||
|
{
|
||||||
|
partial class AppleDOS : Filesystem
|
||||||
|
{
|
||||||
|
public override Errno GetAttributes(string path, ref FileAttributes attributes)
|
||||||
|
{
|
||||||
|
if(!mounted)
|
||||||
|
return Errno.AccessDenied;
|
||||||
|
|
||||||
|
string[] pathElements = path.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
if(pathElements.Length != 1)
|
||||||
|
return Errno.NotSupported;
|
||||||
|
|
||||||
|
string filename = pathElements[0].ToUpperInvariant();
|
||||||
|
|
||||||
|
if(!fileCache.ContainsKey(filename))
|
||||||
|
return Errno.NoSuchFile;
|
||||||
|
|
||||||
|
attributes = new FileAttributes();
|
||||||
|
attributes = FileAttributes.Extents;
|
||||||
|
attributes |= FileAttributes.File;
|
||||||
|
if(lockedFiles.Contains(filename))
|
||||||
|
attributes |= FileAttributes.ReadOnly;
|
||||||
|
|
||||||
|
if(debug &&
|
||||||
|
(string.Compare(path, "$", StringComparison.InvariantCulture) == 0
|
||||||
|
|| string.Compare(path, "$Boot", StringComparison.InvariantCulture) == 0
|
||||||
|
|| string.Compare(path, "$Vtoc", StringComparison.InvariantCulture) == 0))
|
||||||
|
{
|
||||||
|
attributes |= FileAttributes.System;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Errno.NoError;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Errno Read(string path, long offset, long size, ref byte[] buf)
|
||||||
|
{
|
||||||
|
if(!mounted)
|
||||||
|
return Errno.AccessDenied;
|
||||||
|
|
||||||
|
string[] pathElements = path.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
if(pathElements.Length != 1)
|
||||||
|
return Errno.NotSupported;
|
||||||
|
|
||||||
|
byte[] file;
|
||||||
|
Errno error;
|
||||||
|
string filename = pathElements[0].ToUpperInvariant();
|
||||||
|
if(filename.Length > 30)
|
||||||
|
return Errno.NameTooLong;
|
||||||
|
|
||||||
|
if(debug &&
|
||||||
|
(string.Compare(path, "$", StringComparison.InvariantCulture) == 0
|
||||||
|
|| string.Compare(path, "$Boot", StringComparison.InvariantCulture) == 0
|
||||||
|
|| string.Compare(path, "$Vtoc", StringComparison.InvariantCulture) == 0))
|
||||||
|
{
|
||||||
|
if(string.Compare(path, "$", StringComparison.InvariantCulture) == 0)
|
||||||
|
file = catalogBlocks;
|
||||||
|
if(string.Compare(path, "$Vtoc", StringComparison.InvariantCulture) == 0)
|
||||||
|
file = vtocBlocks;
|
||||||
|
else
|
||||||
|
file = bootBlocks;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(!fileCache.TryGetValue(filename, out file))
|
||||||
|
{
|
||||||
|
error = CacheFile(filename);
|
||||||
|
if(error != Errno.NoError)
|
||||||
|
return error;
|
||||||
|
|
||||||
|
if(!fileCache.TryGetValue(filename, out file))
|
||||||
|
return Errno.InvalidArgument;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(offset >= file.Length)
|
||||||
|
return Errno.InvalidArgument;
|
||||||
|
|
||||||
|
if(size + offset >= file.Length)
|
||||||
|
size = file.Length - offset;
|
||||||
|
|
||||||
|
buf = new byte[size];
|
||||||
|
|
||||||
|
Array.Copy(file, offset, buf, 0, size);
|
||||||
|
|
||||||
|
return Errno.NoError;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Errno Stat(string path, ref FileEntryInfo stat)
|
||||||
|
{
|
||||||
|
if(!mounted)
|
||||||
|
return Errno.AccessDenied;
|
||||||
|
|
||||||
|
string[] pathElements = path.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
if(pathElements.Length != 1)
|
||||||
|
return Errno.NotSupported;
|
||||||
|
|
||||||
|
string filename = pathElements[0].ToUpperInvariant();
|
||||||
|
if(filename.Length > 30)
|
||||||
|
return Errno.NameTooLong;
|
||||||
|
|
||||||
|
if(!fileCache.ContainsKey(filename))
|
||||||
|
return Errno.NoSuchFile;
|
||||||
|
|
||||||
|
int filesize;
|
||||||
|
FileAttributes attrs = new FileAttributes();
|
||||||
|
|
||||||
|
fileSizeCache.TryGetValue(filename, out filesize);
|
||||||
|
GetAttributes(path, ref attrs);
|
||||||
|
|
||||||
|
stat = new FileEntryInfo();
|
||||||
|
|
||||||
|
if(debug &&
|
||||||
|
(string.Compare(path, "$", StringComparison.InvariantCulture) == 0
|
||||||
|
|| string.Compare(path, "$Boot", StringComparison.InvariantCulture) == 0
|
||||||
|
|| string.Compare(path, "$Vtoc", StringComparison.InvariantCulture) == 0))
|
||||||
|
{
|
||||||
|
if(string.Compare(path, "$", StringComparison.InvariantCulture) == 0)
|
||||||
|
stat.Length = catalogBlocks.Length;
|
||||||
|
else if(string.Compare(path, "$Boot", StringComparison.InvariantCulture) == 0)
|
||||||
|
stat.Length = bootBlocks.Length;
|
||||||
|
else if(string.Compare(path, "$Vtoc", StringComparison.InvariantCulture) == 0)
|
||||||
|
stat.Length = vtocBlocks.Length;
|
||||||
|
|
||||||
|
stat.Blocks = stat.Length / vtoc.bytesPerSector;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
stat.Length = filesize;
|
||||||
|
stat.Blocks = stat.Length / vtoc.bytesPerSector;
|
||||||
|
}
|
||||||
|
|
||||||
|
stat.Attributes = attrs;
|
||||||
|
stat.BlockSize = vtoc.bytesPerSector;
|
||||||
|
stat.Links = 1;
|
||||||
|
|
||||||
|
return Errno.NoError;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override Errno MapBlock(string path, long fileBlock, ref long deviceBlock)
|
||||||
|
{
|
||||||
|
if(!mounted)
|
||||||
|
return Errno.AccessDenied;
|
||||||
|
|
||||||
|
// TODO: Not really important.
|
||||||
|
return Errno.NotImplemented;
|
||||||
|
}
|
||||||
|
|
||||||
|
Errno CacheFile(string path)
|
||||||
|
{
|
||||||
|
string[] pathElements = path.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
if(pathElements.Length != 1)
|
||||||
|
return Errno.NotSupported;
|
||||||
|
|
||||||
|
string filename = pathElements[0].ToUpperInvariant();
|
||||||
|
if(filename.Length > 30)
|
||||||
|
return Errno.NameTooLong;
|
||||||
|
|
||||||
|
ushort ts;
|
||||||
|
|
||||||
|
if(!catalogCache.TryGetValue(filename, out ts))
|
||||||
|
return Errno.NoSuchFile;
|
||||||
|
|
||||||
|
ulong lba = (ulong)((((ts & 0xFF00) >> 8) * sectorsPerTrack) + (ts & 0xFF));
|
||||||
|
MemoryStream fileMs = new MemoryStream();
|
||||||
|
MemoryStream tsListMs = new MemoryStream();
|
||||||
|
ushort expectedBlock = 0;
|
||||||
|
|
||||||
|
while(lba != 0)
|
||||||
|
{
|
||||||
|
usedSectors++;
|
||||||
|
byte[] tsSector_b = device.ReadSector(lba);
|
||||||
|
if(debug)
|
||||||
|
tsListMs.Write(tsSector_b, 0, tsSector_b.Length);
|
||||||
|
|
||||||
|
// Read the track/sector list sector
|
||||||
|
TrackSectorList tsSector = new TrackSectorList();
|
||||||
|
IntPtr tsPtr = Marshal.AllocHGlobal(256);
|
||||||
|
Marshal.Copy(tsSector_b, 0, tsPtr, 256);
|
||||||
|
tsSector = (TrackSectorList)Marshal.PtrToStructure(tsPtr, typeof(TrackSectorList));
|
||||||
|
Marshal.FreeHGlobal(tsPtr);
|
||||||
|
|
||||||
|
if(tsSector.sectorOffset > expectedBlock)
|
||||||
|
{
|
||||||
|
byte[] hole = new byte[(tsSector.sectorOffset - expectedBlock) * vtoc.bytesPerSector];
|
||||||
|
fileMs.Write(hole, 0, hole.Length);
|
||||||
|
expectedBlock = tsSector.sectorOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach(TrackSectorListEntry entry in tsSector.entries)
|
||||||
|
{
|
||||||
|
track1UsedByFiles |= entry.track == 1;
|
||||||
|
track2UsedByFiles |= entry.track == 2;
|
||||||
|
usedSectors++;
|
||||||
|
|
||||||
|
ulong blockLba = (ulong)((entry.track * sectorsPerTrack) + entry.sector);
|
||||||
|
if(blockLba == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
byte[] fileBlock = device.ReadSector(blockLba);
|
||||||
|
fileMs.Write(fileBlock, 0, fileBlock.Length);
|
||||||
|
expectedBlock++;
|
||||||
|
}
|
||||||
|
|
||||||
|
lba = (ulong)((tsSector.nextListTrack * sectorsPerTrack) + tsSector.nextListSector);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(fileCache.ContainsKey(filename))
|
||||||
|
fileCache.Remove(filename);
|
||||||
|
if(extentCache.ContainsKey(filename))
|
||||||
|
extentCache.Remove(filename);
|
||||||
|
|
||||||
|
fileCache.Add(filename, fileMs.ToArray());
|
||||||
|
extentCache.Add(filename, tsListMs.ToArray());
|
||||||
|
|
||||||
|
return Errno.NoError;
|
||||||
|
}
|
||||||
|
|
||||||
|
Errno CacheAllFiles()
|
||||||
|
{
|
||||||
|
fileCache = new Dictionary<string, byte[]>();
|
||||||
|
extentCache = new Dictionary<string, byte[]>();
|
||||||
|
Errno error;
|
||||||
|
|
||||||
|
foreach(string file in catalogCache.Keys)
|
||||||
|
{
|
||||||
|
error = CacheFile(file);
|
||||||
|
if(error != Errno.NoError)
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint tracksOnBoot = 1;
|
||||||
|
if(!track1UsedByFiles)
|
||||||
|
tracksOnBoot++;
|
||||||
|
if(!track2UsedByFiles)
|
||||||
|
tracksOnBoot++;
|
||||||
|
|
||||||
|
bootBlocks = device.ReadSectors(0, (uint)(tracksOnBoot * sectorsPerTrack));
|
||||||
|
usedSectors += bootBlocks.Length / vtoc.bytesPerSector;
|
||||||
|
|
||||||
|
return Errno.NoError;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
106
DiscImageChef.Filesystems/AppleDOS/Info.cs
Normal file
106
DiscImageChef.Filesystems/AppleDOS/Info.cs
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
// /***************************************************************************
|
||||||
|
// The Disc Image Chef
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Filename : Info.cs
|
||||||
|
// Author(s) : Natalia Portillo <claunia@claunia.com>
|
||||||
|
//
|
||||||
|
// Component : Apple DOS filesystem plugin.
|
||||||
|
//
|
||||||
|
// --[ Description ] ----------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Identifies the Apple DOS filesystem and shows information.
|
||||||
|
//
|
||||||
|
// --[ License ] --------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// This library is free software; you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Lesser General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2.1 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This library is distributed in the hope that it will be useful, but
|
||||||
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public
|
||||||
|
// License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// Copyright © 2011-2016 Natalia Portillo
|
||||||
|
// ****************************************************************************/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
using DiscImageChef.ImagePlugins;
|
||||||
|
|
||||||
|
namespace DiscImageChef.Filesystems.AppleDOS
|
||||||
|
{
|
||||||
|
partial class AppleDOS : Filesystem
|
||||||
|
{
|
||||||
|
public override bool Identify(ImagePlugin imagePlugin, ulong partitionStart, ulong partitionEnd)
|
||||||
|
{
|
||||||
|
if(imagePlugin.ImageInfo.sectors != 455 && imagePlugin.ImageInfo.sectors != 560)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(partitionStart > 0 || imagePlugin.ImageInfo.sectorSize != 256)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
int spt = 0;
|
||||||
|
if(imagePlugin.ImageInfo.sectors == 455)
|
||||||
|
spt = 13;
|
||||||
|
else
|
||||||
|
spt = 16;
|
||||||
|
|
||||||
|
byte[] vtoc_b = imagePlugin.ReadSector((ulong)(17 * spt));
|
||||||
|
vtoc = new VTOC();
|
||||||
|
IntPtr vtocPtr = Marshal.AllocHGlobal(256);
|
||||||
|
Marshal.Copy(vtoc_b, 0, vtocPtr, 256);
|
||||||
|
vtoc = (VTOC)Marshal.PtrToStructure(vtocPtr, typeof(VTOC));
|
||||||
|
Marshal.FreeHGlobal(vtocPtr);
|
||||||
|
|
||||||
|
return vtoc.catalogSector < spt && vtoc.maxTrackSectorPairsPerSector <= 122 && vtoc.sectorsPerTrack == spt && vtoc.bytesPerSector == 256;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void GetInformation(ImagePlugin imagePlugin, ulong partitionStart, ulong partitionEnd, out string information)
|
||||||
|
{
|
||||||
|
information = "";
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
|
||||||
|
int spt = 0;
|
||||||
|
if(imagePlugin.ImageInfo.sectors == 455)
|
||||||
|
spt = 13;
|
||||||
|
else
|
||||||
|
spt = 16;
|
||||||
|
|
||||||
|
byte[] vtoc_b = imagePlugin.ReadSector((ulong)(17 * spt));
|
||||||
|
vtoc = new VTOC();
|
||||||
|
IntPtr vtocPtr = Marshal.AllocHGlobal(256);
|
||||||
|
Marshal.Copy(vtoc_b, 0, vtocPtr, 256);
|
||||||
|
vtoc = (VTOC)Marshal.PtrToStructure(vtocPtr, typeof(VTOC));
|
||||||
|
Marshal.FreeHGlobal(vtocPtr);
|
||||||
|
|
||||||
|
sb.AppendLine("Apple DOS File System");
|
||||||
|
sb.AppendLine();
|
||||||
|
sb.AppendFormat("Catalog starts at sector {0} of track {1}", vtoc.catalogSector, vtoc.catalogTrack).AppendLine();
|
||||||
|
sb.AppendFormat("File system initialized by DOS release {0}", vtoc.dosRelease).AppendLine();
|
||||||
|
sb.AppendFormat("Disk volume number {0}", vtoc.volumeNumber).AppendLine();
|
||||||
|
sb.AppendFormat("Sectors allocated at most in track {0}", vtoc.lastAllocatedSector).AppendLine();
|
||||||
|
sb.AppendFormat("{0} tracks in volume", vtoc.tracks).AppendLine();
|
||||||
|
sb.AppendFormat("{0} sectors per track", vtoc.sectorsPerTrack).AppendLine();
|
||||||
|
sb.AppendFormat("{0} bytes per sector", vtoc.bytesPerSector).AppendLine();
|
||||||
|
sb.AppendFormat("Track allocation is {0}", vtoc.allocationDirection > 0 ? "forward" : "reverse").AppendLine();
|
||||||
|
|
||||||
|
information = sb.ToString();
|
||||||
|
|
||||||
|
xmlFSType = new Schemas.FileSystemType();
|
||||||
|
xmlFSType.Bootable = true;
|
||||||
|
xmlFSType.Clusters = (long)imagePlugin.ImageInfo.sectors;
|
||||||
|
xmlFSType.ClusterSize = (int)imagePlugin.ImageInfo.sectorSize;
|
||||||
|
xmlFSType.Type = "Apple DOS";
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
110
DiscImageChef.Filesystems/AppleDOS/Structs.cs
Normal file
110
DiscImageChef.Filesystems/AppleDOS/Structs.cs
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
// /***************************************************************************
|
||||||
|
// The Disc Image Chef
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Filename : Structs.cs
|
||||||
|
// Author(s) : Natalia Portillo <claunia@claunia.com>
|
||||||
|
//
|
||||||
|
// Component : Apple DOS filesystem plugin.
|
||||||
|
//
|
||||||
|
// --[ Description ] ----------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Apple DOS filesystem structures.
|
||||||
|
//
|
||||||
|
// --[ License ] --------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// This library is free software; you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Lesser General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2.1 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This library is distributed in the hope that it will be useful, but
|
||||||
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public
|
||||||
|
// License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// Copyright © 2011-2016 Natalia Portillo
|
||||||
|
// ****************************************************************************/
|
||||||
|
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace DiscImageChef.Filesystems.AppleDOS
|
||||||
|
{
|
||||||
|
partial class AppleDOS : Filesystem
|
||||||
|
{
|
||||||
|
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||||
|
struct VTOC
|
||||||
|
{
|
||||||
|
public byte unused1;
|
||||||
|
public byte catalogTrack;
|
||||||
|
public byte catalogSector;
|
||||||
|
public byte dosRelease;
|
||||||
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
|
||||||
|
public byte[] unused2;
|
||||||
|
public byte volumeNumber;
|
||||||
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
|
||||||
|
public byte[] unused3;
|
||||||
|
public byte maxTrackSectorPairsPerSector;
|
||||||
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
|
||||||
|
public byte[] unused4;
|
||||||
|
public byte lastAllocatedSector;
|
||||||
|
public sbyte allocationDirection;
|
||||||
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
|
||||||
|
public byte[] unused5;
|
||||||
|
public byte tracks;
|
||||||
|
public byte sectorsPerTrack;
|
||||||
|
public ushort bytesPerSector;
|
||||||
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 200)]
|
||||||
|
public byte[] bitmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||||
|
struct CatalogSector
|
||||||
|
{
|
||||||
|
public byte unused1;
|
||||||
|
public byte trackOfNext;
|
||||||
|
public byte sectorOfNext;
|
||||||
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
|
||||||
|
public byte[] unused2;
|
||||||
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 7)]
|
||||||
|
public FileEntry[] entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||||
|
struct FileEntry
|
||||||
|
{
|
||||||
|
public byte extentTrack;
|
||||||
|
public byte extentSector;
|
||||||
|
public byte typeAndFlags;
|
||||||
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 30)]
|
||||||
|
public byte[] filename;
|
||||||
|
public ushort length;
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||||
|
struct TrackSectorList
|
||||||
|
{
|
||||||
|
public byte unused1;
|
||||||
|
public byte nextListTrack;
|
||||||
|
public byte nextListSector;
|
||||||
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
|
||||||
|
public byte[] unused2;
|
||||||
|
public ushort sectorOffset;
|
||||||
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
|
||||||
|
public byte[] unused3;
|
||||||
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 122)]
|
||||||
|
public TrackSectorListEntry[] entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||||
|
struct TrackSectorListEntry
|
||||||
|
{
|
||||||
|
public byte track;
|
||||||
|
public byte sector;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
153
DiscImageChef.Filesystems/AppleDOS/Super.cs
Normal file
153
DiscImageChef.Filesystems/AppleDOS/Super.cs
Normal file
@@ -0,0 +1,153 @@
|
|||||||
|
// /***************************************************************************
|
||||||
|
// The Disc Image Chef
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Filename : Super.cs
|
||||||
|
// Author(s) : Natalia Portillo <claunia@claunia.com>
|
||||||
|
//
|
||||||
|
// Component : Apple DOS filesystem plugin.
|
||||||
|
//
|
||||||
|
// --[ Description ] ----------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Handles mounting and umounting the Apple DOS filesystem.
|
||||||
|
//
|
||||||
|
// --[ License ] --------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// This library is free software; you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Lesser General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2.1 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This library is distributed in the hope that it will be useful, but
|
||||||
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public
|
||||||
|
// License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// Copyright © 2011-2016 Natalia Portillo
|
||||||
|
// ****************************************************************************/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using DiscImageChef.Console;
|
||||||
|
|
||||||
|
namespace DiscImageChef.Filesystems.AppleDOS
|
||||||
|
{
|
||||||
|
partial class AppleDOS : Filesystem
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Mounts an Apple Lisa filesystem
|
||||||
|
/// </summary>
|
||||||
|
public override Errno Mount()
|
||||||
|
{
|
||||||
|
return Mount(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Mounts an Apple Lisa filesystem
|
||||||
|
/// </summary>
|
||||||
|
public override Errno Mount(bool debug)
|
||||||
|
{
|
||||||
|
if(device.ImageInfo.sectors != 455 && device.ImageInfo.sectors != 560)
|
||||||
|
{
|
||||||
|
DicConsole.DebugWriteLine("Apple DOS plugin", "Incorrect device size.");
|
||||||
|
return Errno.InOutError;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(start > 0)
|
||||||
|
{
|
||||||
|
DicConsole.DebugWriteLine("Apple DOS plugin", "Partitions are not supported.");
|
||||||
|
return Errno.InOutError;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(device.ImageInfo.sectorSize != 256)
|
||||||
|
{
|
||||||
|
DicConsole.DebugWriteLine("Apple DOS plugin", "Incorrect sector size.");
|
||||||
|
return Errno.InOutError;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(device.ImageInfo.sectors == 455)
|
||||||
|
sectorsPerTrack = 13;
|
||||||
|
else
|
||||||
|
sectorsPerTrack = 16;
|
||||||
|
|
||||||
|
// Read the VTOC
|
||||||
|
byte[] vtoc_b = device.ReadSector((ulong)(17 * sectorsPerTrack));
|
||||||
|
vtoc = new VTOC();
|
||||||
|
IntPtr vtocPtr = Marshal.AllocHGlobal(256);
|
||||||
|
Marshal.Copy(vtoc_b, 0, vtocPtr, 256);
|
||||||
|
vtoc = (VTOC)Marshal.PtrToStructure(vtocPtr, typeof(VTOC));
|
||||||
|
Marshal.FreeHGlobal(vtocPtr);
|
||||||
|
|
||||||
|
track1UsedByFiles = false;
|
||||||
|
track2UsedByFiles = false;
|
||||||
|
usedSectors = 1;
|
||||||
|
|
||||||
|
Errno error;
|
||||||
|
|
||||||
|
error = ReadCatalog();
|
||||||
|
if(error != Errno.NoError)
|
||||||
|
{
|
||||||
|
DicConsole.DebugWriteLine("Apple DOS plugin", "Unable to read catalog.");
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
error = CacheAllFiles();
|
||||||
|
if(error != Errno.NoError)
|
||||||
|
{
|
||||||
|
DicConsole.DebugWriteLine("Apple DOS plugin", "Unable cache all files.");
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create XML metadata for mounted filesystem
|
||||||
|
xmlFSType = new Schemas.FileSystemType();
|
||||||
|
xmlFSType.Bootable = true;
|
||||||
|
xmlFSType.Clusters = (long)device.ImageInfo.sectors;
|
||||||
|
xmlFSType.ClusterSize = vtoc.bytesPerSector;
|
||||||
|
xmlFSType.Files = catalogCache.Count;
|
||||||
|
xmlFSType.FilesSpecified = true;
|
||||||
|
xmlFSType.FreeClusters = xmlFSType.Clusters - usedSectors;
|
||||||
|
xmlFSType.FreeClustersSpecified = true;
|
||||||
|
xmlFSType.Type = "Apple DOS";
|
||||||
|
|
||||||
|
this.debug = debug;
|
||||||
|
mounted = true;
|
||||||
|
return Errno.NoError;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Umounts this Lisa filesystem
|
||||||
|
/// </summary>
|
||||||
|
public override Errno Unmount()
|
||||||
|
{
|
||||||
|
mounted = false;
|
||||||
|
extentCache = null;
|
||||||
|
fileCache = null;
|
||||||
|
catalogCache = null;
|
||||||
|
fileSizeCache = null;
|
||||||
|
|
||||||
|
return Errno.NoError;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets information about the mounted volume.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="stat">Information about the mounted volume.</param>
|
||||||
|
public override Errno StatFs(ref FileSystemInfo stat)
|
||||||
|
{
|
||||||
|
stat = new FileSystemInfo();
|
||||||
|
stat.Blocks = (long)device.ImageInfo.sectors;
|
||||||
|
stat.FilenameLength = 30;
|
||||||
|
stat.Files = (ulong)catalogCache.Count;
|
||||||
|
stat.FreeBlocks = stat.Blocks - usedSectors;
|
||||||
|
stat.FreeFiles = totalFileEntries - stat.Files;
|
||||||
|
stat.PluginId = PluginUUID;
|
||||||
|
stat.Type = "Apple DOS";
|
||||||
|
|
||||||
|
return Errno.NoError;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
135
DiscImageChef.Filesystems/AppleDOS/Xattr.cs
Normal file
135
DiscImageChef.Filesystems/AppleDOS/Xattr.cs
Normal file
@@ -0,0 +1,135 @@
|
|||||||
|
// /***************************************************************************
|
||||||
|
// The Disc Image Chef
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Filename : Xattr.cs
|
||||||
|
// Author(s) : Natalia Portillo <claunia@claunia.com>
|
||||||
|
//
|
||||||
|
// Component : Apple DOS filesystem plugin.
|
||||||
|
//
|
||||||
|
// --[ Description ] ----------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Methods to handle Apple DOS extended attributes (file type).
|
||||||
|
//
|
||||||
|
// --[ License ] --------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// This library is free software; you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Lesser General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2.1 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This library is distributed in the hope that it will be useful, but
|
||||||
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public
|
||||||
|
// License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// Copyright © 2011-2016 Natalia Portillo
|
||||||
|
// ****************************************************************************/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace DiscImageChef.Filesystems.AppleDOS
|
||||||
|
{
|
||||||
|
partial class AppleDOS : Filesystem
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Lists all extended attributes, alternate data streams and forks of the given file.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>Error number.</returns>
|
||||||
|
/// <param name="path">Path.</param>
|
||||||
|
/// <param name="xattrs">List of extended attributes, alternate data streams and forks.</param>
|
||||||
|
public override Errno ListXAttr(string path, ref List<string> xattrs)
|
||||||
|
{
|
||||||
|
if(!mounted)
|
||||||
|
return Errno.AccessDenied;
|
||||||
|
|
||||||
|
string[] pathElements = path.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
if(pathElements.Length != 1)
|
||||||
|
return Errno.NotSupported;
|
||||||
|
|
||||||
|
string filename = pathElements[0].ToUpperInvariant();
|
||||||
|
if(filename.Length > 30)
|
||||||
|
return Errno.NameTooLong;
|
||||||
|
|
||||||
|
xattrs = new List<string>();
|
||||||
|
|
||||||
|
if(debug &&
|
||||||
|
(string.Compare(path, "$", StringComparison.InvariantCulture) == 0
|
||||||
|
|| string.Compare(path, "$Boot", StringComparison.InvariantCulture) == 0
|
||||||
|
|| string.Compare(path, "$Vtoc", StringComparison.InvariantCulture) == 0))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(!catalogCache.ContainsKey(filename))
|
||||||
|
return Errno.NoSuchFile;
|
||||||
|
|
||||||
|
xattrs.Add("com.apple.dos.type");
|
||||||
|
|
||||||
|
if(debug)
|
||||||
|
xattrs.Add("com.apple.dos.tracksectorlist");
|
||||||
|
}
|
||||||
|
|
||||||
|
return Errno.NoError;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Reads an extended attribute, alternate data stream or fork from the given file.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>Error number.</returns>
|
||||||
|
/// <param name="path">File path.</param>
|
||||||
|
/// <param name="xattr">Extended attribute, alternate data stream or fork name.</param>
|
||||||
|
/// <param name="buf">Buffer.</param>
|
||||||
|
public override Errno GetXattr(string path, string xattr, ref byte[] buf)
|
||||||
|
{
|
||||||
|
if(!mounted)
|
||||||
|
return Errno.AccessDenied;
|
||||||
|
|
||||||
|
string[] pathElements = path.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
if(pathElements.Length != 1)
|
||||||
|
return Errno.NotSupported;
|
||||||
|
|
||||||
|
string filename = pathElements[0].ToUpperInvariant();
|
||||||
|
if(filename.Length > 30)
|
||||||
|
return Errno.NameTooLong;
|
||||||
|
|
||||||
|
if(debug &&
|
||||||
|
(string.Compare(path, "$", StringComparison.InvariantCulture) == 0
|
||||||
|
|| string.Compare(path, "$Boot", StringComparison.InvariantCulture) == 0
|
||||||
|
|| string.Compare(path, "$Vtoc", StringComparison.InvariantCulture) == 0))
|
||||||
|
{
|
||||||
|
return Errno.NoSuchExtendedAttribute;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!catalogCache.ContainsKey(filename))
|
||||||
|
return Errno.NoSuchFile;
|
||||||
|
|
||||||
|
if(string.Compare(xattr, "com.apple.dos.type", StringComparison.InvariantCulture) == 0)
|
||||||
|
{
|
||||||
|
byte type;
|
||||||
|
if(!fileTypeCache.TryGetValue(filename, out type))
|
||||||
|
return Errno.InvalidArgument;
|
||||||
|
buf = new byte[1];
|
||||||
|
buf[0] = type;
|
||||||
|
return Errno.NoError;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(string.Compare(xattr, "com.apple.dos.tracksectorlist", StringComparison.InvariantCulture) == 0 && debug)
|
||||||
|
{
|
||||||
|
byte[] ts;
|
||||||
|
if(!extentCache.TryGetValue(filename, out ts))
|
||||||
|
return Errno.InvalidArgument;
|
||||||
|
buf = new byte[ts.Length];
|
||||||
|
Array.Copy(ts, 0, buf, 0, buf.Length);
|
||||||
|
return Errno.NoError;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Errno.NoSuchExtendedAttribute;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,3 +1,15 @@
|
|||||||
|
2016-10-07 Natalia Portillo <claunia@claunia.com>
|
||||||
|
|
||||||
|
* Dir.cs:
|
||||||
|
* Info.cs:
|
||||||
|
* File.cs:
|
||||||
|
* Xattr.cs:
|
||||||
|
* Super.cs:
|
||||||
|
* Structs.cs:
|
||||||
|
* AppleDOS.cs:
|
||||||
|
* DiscImageChef.Filesystems.csproj: Adds support for Apple DOS
|
||||||
|
filesystem, closes #33.
|
||||||
|
|
||||||
2016-09-05 Natalia Portillo <claunia@claunia.com>
|
2016-09-05 Natalia Portillo <claunia@claunia.com>
|
||||||
|
|
||||||
* Info.cs: Do not throw identification exceptions.
|
* Info.cs: Do not throw identification exceptions.
|
||||||
|
|||||||
@@ -116,6 +116,13 @@
|
|||||||
<Compile Include="ECMA67.cs" />
|
<Compile Include="ECMA67.cs" />
|
||||||
<Compile Include="FATX.cs" />
|
<Compile Include="FATX.cs" />
|
||||||
<Compile Include="ZFS.cs" />
|
<Compile Include="ZFS.cs" />
|
||||||
|
<Compile Include="AppleDOS\Dir.cs" />
|
||||||
|
<Compile Include="AppleDOS\File.cs" />
|
||||||
|
<Compile Include="AppleDOS\Info.cs" />
|
||||||
|
<Compile Include="AppleDOS\AppleDOS.cs" />
|
||||||
|
<Compile Include="AppleDOS\Structs.cs" />
|
||||||
|
<Compile Include="AppleDOS\Super.cs" />
|
||||||
|
<Compile Include="AppleDOS\Xattr.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -157,6 +164,7 @@
|
|||||||
<Folder Include="UCSDPascal\" />
|
<Folder Include="UCSDPascal\" />
|
||||||
<Folder Include="AppleMFS\" />
|
<Folder Include="AppleMFS\" />
|
||||||
<Folder Include="CPM\" />
|
<Folder Include="CPM\" />
|
||||||
|
<Folder Include="AppleDOS\" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<EmbeddedResource Include="..\LICENSE.LGPL">
|
<EmbeddedResource Include="..\LICENSE.LGPL">
|
||||||
@@ -168,8 +176,8 @@
|
|||||||
<MonoDevelop>
|
<MonoDevelop>
|
||||||
<Properties>
|
<Properties>
|
||||||
<Policies>
|
<Policies>
|
||||||
<TextStylePolicy FileWidth="120" inheritsSet="VisualStudio" inheritsScope="text/plain" scope="text/x-csharp" />
|
<TextStylePolicy TabWidth="4" TabsToSpaces="True" IndentWidth="4" RemoveTrailingWhitespace="True" NoTabsAfterNonTabs="False" EolMarker="Native" FileWidth="120" inheritsSet="VisualStudio" inheritsScope="text/plain" scope="text/x-csharp" />
|
||||||
<CSharpFormattingPolicy IndentSwitchSection="True" NewLinesForBracesInProperties="True" NewLinesForBracesInAccessors="True" NewLinesForBracesInAnonymousMethods="True" NewLinesForBracesInControlBlocks="True" NewLinesForBracesInAnonymousTypes="True" NewLinesForBracesInObjectCollectionArrayInitializers="True" NewLinesForBracesInLambdaExpressionBody="True" NewLineForElse="True" NewLineForCatch="True" NewLineForFinally="True" NewLineForMembersInObjectInit="True" NewLineForMembersInAnonymousTypes="True" NewLineForClausesInQuery="True" SpacingAfterMethodDeclarationName="False" SpaceAfterMethodCallName="False" SpaceAfterControlFlowStatementKeyword="False" SpaceBeforeOpenSquareBracket="False" inheritsSet="Mono" inheritsScope="text/x-csharp" scope="text/x-csharp" />
|
<CSharpFormattingPolicy IndentBlock="True" IndentBraces="False" IndentSwitchCaseSection="True" LabelPositioning="OneLess" NewLinesForBracesInTypes="True" NewLinesForBracesInMethods="True" SpaceWithinMethodDeclarationParenthesis="False" SpaceBetweenEmptyMethodDeclarationParentheses="False" SpaceWithinMethodCallParentheses="False" SpaceBetweenEmptyMethodCallParentheses="False" SpaceWithinExpressionParentheses="False" SpaceWithinCastParentheses="False" SpaceWithinOtherParentheses="False" SpaceAfterCast="False" SpacesIgnoreAroundVariableDeclaration="False" SpaceBetweenEmptySquareBrackets="False" SpaceWithinSquareBrackets="False" SpaceAfterColonInBaseTypeDeclaration="True" SpaceAfterComma="True" SpaceAfterDot="False" SpaceAfterSemicolonsInForStatement="True" SpaceBeforeColonInBaseTypeDeclaration="True" SpaceBeforeComma="False" SpaceBeforeDot="False" SpaceBeforeSemicolonsInForStatement="False" SpacingAroundBinaryOperator="Single" WrappingPreserveSingleLine="True" WrappingKeepStatementsOnSingleLine="True" PlaceSystemDirectiveFirst="True" IndentSwitchSection="True" NewLinesForBracesInProperties="True" NewLinesForBracesInAccessors="True" NewLinesForBracesInAnonymousMethods="True" NewLinesForBracesInControlBlocks="True" NewLinesForBracesInAnonymousTypes="True" NewLinesForBracesInObjectCollectionArrayInitializers="True" NewLinesForBracesInLambdaExpressionBody="True" NewLineForElse="True" NewLineForCatch="True" NewLineForFinally="True" NewLineForMembersInObjectInit="True" NewLineForMembersInAnonymousTypes="True" NewLineForClausesInQuery="True" SpacingAfterMethodDeclarationName="False" SpaceAfterMethodCallName="False" SpaceAfterControlFlowStatementKeyword="False" SpaceBeforeOpenSquareBracket="False" inheritsSet="Mono" inheritsScope="text/x-csharp" scope="text/x-csharp" />
|
||||||
<DotNetNamingPolicy DirectoryNamespaceAssociation="PrefixedHierarchical" ResourceNamePolicy="MSBuild" />
|
<DotNetNamingPolicy DirectoryNamespaceAssociation="PrefixedHierarchical" ResourceNamePolicy="MSBuild" />
|
||||||
<StandardHeader Text="/***************************************************************************
The Disc Image Chef
----------------------------------------------------------------------------
 
Filename : ${FileName}
Author(s) : ${AuthorName} <${AuthorEmail}>

Component : Component
 
--[ Description ] ----------------------------------------------------------
 
 Description
 
--[ License ] --------------------------------------------------------------
 
 This library is free software; you can redistribute it and/or modify
 it under the terms of the GNU Lesser General Public License as
 published by the Free Software Foundation; either version 2.1 of the
 License, or (at your option) any later version.

 This library is distributed in the hope that it will be useful, but
 WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 Lesser General Public License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with this library; if not, see <http://www.gnu.org/licenses/>.

----------------------------------------------------------------------------
Copyright © 2011-${Year} ${CopyrightHolder}
****************************************************************************/" IncludeInNewFiles="True" />
|
<StandardHeader Text="/***************************************************************************
The Disc Image Chef
----------------------------------------------------------------------------
 
Filename : ${FileName}
Author(s) : ${AuthorName} <${AuthorEmail}>

Component : Component
 
--[ Description ] ----------------------------------------------------------
 
 Description
 
--[ License ] --------------------------------------------------------------
 
 This library is free software; you can redistribute it and/or modify
 it under the terms of the GNU Lesser General Public License as
 published by the Free Software Foundation; either version 2.1 of the
 License, or (at your option) any later version.

 This library is distributed in the hope that it will be useful, but
 WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 Lesser General Public License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with this library; if not, see <http://www.gnu.org/licenses/>.

----------------------------------------------------------------------------
Copyright © 2011-${Year} ${CopyrightHolder}
****************************************************************************/" IncludeInNewFiles="True" />
|
||||||
</Policies>
|
</Policies>
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ Works under any operating system where there is Mono or .NET Framework. Tested w
|
|||||||
|
|
||||||
Features
|
Features
|
||||||
========
|
========
|
||||||
|
|
||||||
* Can read several disk image formats.
|
* Can read several disk image formats.
|
||||||
* Can read standard sector by sector copies for optical and magnetic discs with constant bytes per sector.
|
* Can read standard sector by sector copies for optical and magnetic discs with constant bytes per sector.
|
||||||
* Can read several known sector by sector formats with variable bytes per sector.
|
* Can read several known sector by sector formats with variable bytes per sector.
|
||||||
@@ -59,6 +58,7 @@ Supported disk image formats
|
|||||||
* Apple New Disk Image Format (NDIF, requires Resource Fork)
|
* Apple New Disk Image Format (NDIF, requires Resource Fork)
|
||||||
* Apple Disk Archival/Retrieval Tool (DART)
|
* Apple Disk Archival/Retrieval Tool (DART)
|
||||||
* MAME Compressed Hunks of Data (CHD)
|
* MAME Compressed Hunks of Data (CHD)
|
||||||
|
* Apple II nibble images (NIB)
|
||||||
|
|
||||||
Supported partitioning schemes
|
Supported partitioning schemes
|
||||||
==============================
|
==============================
|
||||||
@@ -90,6 +90,7 @@ Supported file systems for read-only operations
|
|||||||
* Apple Macintosh File System (MFS)
|
* Apple Macintosh File System (MFS)
|
||||||
* U.C.S.D Pascal file system
|
* U.C.S.D Pascal file system
|
||||||
* CP/M file system
|
* CP/M file system
|
||||||
|
* Apple DOS file system
|
||||||
|
|
||||||
Supported file systems for identification and information only
|
Supported file systems for identification and information only
|
||||||
==============================================================
|
==============================================================
|
||||||
|
|||||||
Reference in New Issue
Block a user