REFACTOR: Final cleanup of DiscImageChef.Filesystems.

This commit is contained in:
2017-12-24 02:37:41 +00:00
parent ec73a6cdc3
commit 4115698ac8
94 changed files with 5196 additions and 5116 deletions

View File

@@ -35,48 +35,48 @@ namespace DiscImageChef.Filesystems.LisaFS
public partial class LisaFS
{
/// <summary>
/// Lisa FS v1, from Lisa OS 1.0 (Workshop or Office)
/// Never seen on Sony floppies.
/// Lisa FS v1, from Lisa OS 1.0 (Workshop or Office)
/// Never seen on Sony floppies.
/// </summary>
const byte LISA_V1 = 0x0E;
/// <summary>
/// Lisa FS v2, from Lisa OS 2.0 (Workshop or Office)
/// Contrary to what most information online says the only difference with V1
/// is the Extents File size. Catalog format is the same
/// Lisa FS v2, from Lisa OS 2.0 (Workshop or Office)
/// Contrary to what most information online says the only difference with V1
/// is the Extents File size. Catalog format is the same
/// </summary>
const byte LISA_V2 = 0x0F;
/// <summary>
/// Lisa FS v3, from Lisa OS 3.0 (Workshop or Office)
/// Adds support for user catalogs (aka subdirectories),
/// and changes the catalog format from extents to double-linked list.
/// Uses '-' as path separator (so people that created Lisa/FILE.TEXT just
/// created a file named like that :p)
/// Lisa FS v3, from Lisa OS 3.0 (Workshop or Office)
/// Adds support for user catalogs (aka subdirectories),
/// and changes the catalog format from extents to double-linked list.
/// Uses '-' as path separator (so people that created Lisa/FILE.TEXT just
/// created a file named like that :p)
/// </summary>
const byte LISA_V3 = 0x11;
/// <summary>Maximum string size in LisaFS</summary>
const uint E_NAME = 32;
/// <summary>
/// Unused file ID
/// Unused file ID
/// </summary>
const ushort FILEID_FREE = 0x0000;
/// <summary>
/// Used by the boot blocks
/// Used by the boot blocks
/// </summary>
const ushort FILEID_BOOT = 0xAAAA;
/// <summary>
/// Used by the operating system loader blocks
/// Used by the operating system loader blocks
/// </summary>
const ushort FILEID_LOADER = 0xBBBB;
/// <summary>
/// Used by the MDDF
/// Used by the MDDF
/// </summary>
const ushort FILEID_MDDF = 0x0001;
/// <summary>
/// Used by the volume bitmap, sits between MDDF and S-Records file.
/// Used by the volume bitmap, sits between MDDF and S-Records file.
/// </summary>
const ushort FILEID_BITMAP = 0x0002;
/// <summary>
/// S-Records file
/// S-Records file
/// </summary>
const ushort FILEID_SRECORD = 0x0003;
/// <summary>The root catalog</summary>
@@ -84,7 +84,7 @@ namespace DiscImageChef.Filesystems.LisaFS
const short FILEID_BOOT_SIGNED = -21846;
const short FILEID_LOADER_SIGNED = -17477;
/// <summary>
/// A file that has been erased
/// A file that has been erased
/// </summary>
const ushort FILEID_ERASED = 0x7FFF;
const ushort FILEID_MAX = FILEID_ERASED;
@@ -95,67 +95,67 @@ namespace DiscImageChef.Filesystems.LisaFS
enum FileType : byte
{
/// <summary>
/// Undefined file type
/// Undefined file type
/// </summary>
Undefined = 0,
/// <summary>
/// MDDF
/// MDDF
/// </summary>
MDDFile = 1,
/// <summary>
/// Root catalog
/// Root catalog
/// </summary>
RootCat = 2,
/// <summary>
/// Bitmap
/// Bitmap
/// </summary>
FreeList = 3,
/// <summary>
/// Unknown, maybe refers to the S-Records File?
/// Unknown, maybe refers to the S-Records File?
/// </summary>
BadBlocks = 4,
/// <summary>
/// System data
/// System data
/// </summary>
SysData = 5,
/// <summary>
/// Printer spool
/// Printer spool
/// </summary>
Spool = 6,
/// <summary>
/// Executable. Yet application files don't use it
/// Executable. Yet application files don't use it
/// </summary>
Exec = 7,
/// <summary>
/// User catalog
/// User catalog
/// </summary>
UserCat = 8,
/// <summary>
/// Pipe. Not seen on disk.
/// Pipe. Not seen on disk.
/// </summary>
Pipe = 9,
/// <summary>
/// Boot file?
/// Boot file?
/// </summary>
BootFile = 10,
/// <summary>
/// Swap for data
/// Swap for data
/// </summary>
SwapData = 11,
/// <summary>
/// Swap for code
/// Swap for code
/// </summary>
SwapCode = 12,
/// <summary>
/// Unknown
/// Unknown
/// </summary>
RamAP = 13,
/// <summary>
/// Any file
/// Any file
/// </summary>
UserFile = 14,
/// <summary>
/// Erased?
/// Erased?
/// </summary>
KilledObject = 15
}

View File

@@ -41,7 +41,7 @@ namespace DiscImageChef.Filesystems.LisaFS
public partial class LisaFS
{
/// <summary>
/// Solves a symbolic link.
/// Solves a symbolic link.
/// </summary>
/// <param name="path">Link path.</param>
/// <param name="dest">Link destination.</param>
@@ -52,7 +52,7 @@ namespace DiscImageChef.Filesystems.LisaFS
}
/// <summary>
/// Lists contents from a directory.
/// Lists contents from a directory.
/// </summary>
/// <param name="path">Directory path.</param>
/// <param name="contents">Directory contents.</param>
@@ -90,13 +90,15 @@ namespace DiscImageChef.Filesystems.LisaFS
{
// Do same trick as Mac OS X, replace filesystem '/' with '-',
// as '-' is the path separator in Lisa OS
contents = (from entry in catalogCache where entry.parentID == dirId select StringHandlers.CToString(entry.filename, CurrentEncoding).Replace('/', '-')).ToList();
contents = (from entry in catalogCache
where entry.parentID == dirId
select StringHandlers.CToString(entry.filename, CurrentEncoding).Replace('/', '-')).ToList();
return Errno.NoError;
}
/// <summary>
/// Reads, interprets and caches the Catalog File
/// Reads, interprets and caches the Catalog File
/// </summary>
Errno ReadCatalog()
{
@@ -215,7 +217,7 @@ namespace DiscImageChef.Filesystems.LisaFS
// Traverse all entries
while(offset + 64 <= buf.Length)
// Catalog block header
// Catalog block header
if(buf[offset + 0x24] == 0x08) offset += 78;
// Maybe just garbage? Found in more than 1 disk
else if(buf[offset + 0x24] == 0x7C) offset += 50;

View File

@@ -46,7 +46,7 @@ namespace DiscImageChef.Filesystems.LisaFS
}
/// <summary>
/// Searches the disk for an extents file (or gets it from cache)
/// Searches the disk for an extents file (or gets it from cache)
/// </summary>
/// <returns>Error.</returns>
/// <param name="fileId">File identifier.</param>
@@ -171,13 +171,11 @@ namespace DiscImageChef.Filesystems.LisaFS
file.extents = new Extent[extentsCount];
for(int j = 0; j < extentsCount; j++)
{
file.extents[j] = new Extent
{
{
start = BigEndianBitConverter.ToInt32(sector, extentsOffset + j * 6),
length = BigEndianBitConverter.ToInt16(sector, extentsOffset + j * 6 + 4)
};
}
extentCache.Add(fileId, file);
@@ -185,77 +183,64 @@ namespace DiscImageChef.Filesystems.LisaFS
if(printedExtents.Contains(fileId)) return Errno.NoError;
DicConsole.DebugWriteLine("LisaFS plugin", "ExtentFile[{0}].filenameLen = {1}", fileId,
file.filenameLen);
DicConsole.DebugWriteLine("LisaFS plugin", "ExtentFile[{0}].filenameLen = {1}", fileId, file.filenameLen);
DicConsole.DebugWriteLine("LisaFS plugin", "ExtentFile[{0}].filename = {1}", fileId,
StringHandlers.CToString(file.filename, CurrentEncoding));
DicConsole.DebugWriteLine("LisaFS plugin", "ExtentFile[{0}].unknown1 = 0x{1:X4}", fileId,
file.unknown1);
DicConsole.DebugWriteLine("LisaFS plugin", "ExtentFile[{0}].file_uid = 0x{1:X16}", fileId,
file.file_uid);
DicConsole.DebugWriteLine("LisaFS plugin", "ExtentFile[{0}].unknown2 = 0x{1:X2}", fileId,
file.unknown2);
DicConsole.DebugWriteLine("LisaFS plugin", "ExtentFile[{0}].unknown1 = 0x{1:X4}", fileId, file.unknown1);
DicConsole.DebugWriteLine("LisaFS plugin", "ExtentFile[{0}].file_uid = 0x{1:X16}", fileId, file.file_uid);
DicConsole.DebugWriteLine("LisaFS plugin", "ExtentFile[{0}].unknown2 = 0x{1:X2}", fileId, file.unknown2);
DicConsole.DebugWriteLine("LisaFS plugin", "ExtentFile[{0}].etype = 0x{1:X2}", fileId, file.etype);
DicConsole.DebugWriteLine("LisaFS plugin", "ExtentFile[{0}].ftype = {1}", fileId, file.ftype);
DicConsole.DebugWriteLine("LisaFS plugin", "ExtentFile[{0}].unknown3 = 0x{1:X2}", fileId,
file.unknown3);
DicConsole.DebugWriteLine("LisaFS plugin", "ExtentFile[{0}].unknown3 = 0x{1:X2}", fileId, file.unknown3);
DicConsole.DebugWriteLine("LisaFS plugin", "ExtentFile[{0}].dtc = {1}", fileId, file.dtc);
DicConsole.DebugWriteLine("LisaFS plugin", "ExtentFile[{0}].dta = {1}", fileId, file.dta);
DicConsole.DebugWriteLine("LisaFS plugin", "ExtentFile[{0}].dtm = {1}", fileId, file.dtm);
DicConsole.DebugWriteLine("LisaFS plugin", "ExtentFile[{0}].dtb = {1}", fileId, file.dtb);
DicConsole.DebugWriteLine("LisaFS plugin", "ExtentFile[{0}].dts = {1}", fileId, file.dts);
DicConsole.DebugWriteLine("LisaFS plugin", "ExtentFile[{0}].serial = {1}", fileId, file.serial);
DicConsole.DebugWriteLine("LisaFS plugin", "ExtentFile[{0}].unknown4 = 0x{1:X2}", fileId,
file.unknown4);
DicConsole.DebugWriteLine("LisaFS plugin", "ExtentFile[{0}].unknown4 = 0x{1:X2}", fileId, file.unknown4);
DicConsole.DebugWriteLine("LisaFS plugin", "ExtentFile[{0}].locked = {1}", fileId, file.locked > 0);
DicConsole.DebugWriteLine("LisaFS plugin", "ExtentFile[{0}].protect = {1}", fileId,
file.protect > 0);
DicConsole.DebugWriteLine("LisaFS plugin", "ExtentFile[{0}].protect = {1}", fileId, file.protect > 0);
DicConsole.DebugWriteLine("LisaFS plugin", "ExtentFile[{0}].master = {1}", fileId, file.master > 0);
DicConsole.DebugWriteLine("LisaFS plugin", "ExtentFile[{0}].scavenged = {1}", fileId,
file.scavenged > 0);
DicConsole.DebugWriteLine("LisaFS plugin", "ExtentFile[{0}].scavenged = {1}", fileId, file.scavenged > 0);
DicConsole.DebugWriteLine("LisaFS plugin", "ExtentFile[{0}].closed = {1}", fileId, file.closed > 0);
DicConsole.DebugWriteLine("LisaFS plugin", "ExtentFile[{0}].open = {1}", fileId, file.open > 0);
DicConsole.DebugWriteLine("LisaFS plugin",
"ExtentFile[{0}].unknown5 = 0x{1:X2}{2:X2}{3:X2}{4:X2}{5:X2}{6:X2}{7:X2}{8:X2}{9:X2}" +
"{10:X2}{11:X2}", fileId, file.unknown5[0], file.unknown5[1],
file.unknown5[2], file.unknown5[3], file.unknown5[4], file.unknown5[5],
file.unknown5[6], file.unknown5[7], file.unknown5[8], file.unknown5[9],
file.unknown5[10]);
"{10:X2}{11:X2}", fileId, file.unknown5[0], file.unknown5[1], file.unknown5[2],
file.unknown5[3], file.unknown5[4], file.unknown5[5], file.unknown5[6],
file.unknown5[7], file.unknown5[8], file.unknown5[9], file.unknown5[10]);
DicConsole.DebugWriteLine("LisaFS plugin", "ExtentFile[{0}].release = {1}", fileId, file.release);
DicConsole.DebugWriteLine("LisaFS plugin", "ExtentFile[{0}].build = {1}", fileId, file.build);
DicConsole.DebugWriteLine("LisaFS plugin", "ExtentFile[{0}].compatibility = {1}", fileId,
file.compatibility);
DicConsole.DebugWriteLine("LisaFS plugin", "ExtentFile[{0}].revision = {1}", fileId, file.revision);
DicConsole.DebugWriteLine("LisaFS plugin", "ExtentFile[{0}].unknown6 = 0x{1:X4}", fileId,
file.unknown6);
DicConsole.DebugWriteLine("LisaFS plugin", "ExtentFile[{0}].unknown6 = 0x{1:X4}", fileId, file.unknown6);
DicConsole.DebugWriteLine("LisaFS plugin", "ExtentFile[{0}].password_valid = {1}", fileId,
file.password_valid > 0);
DicConsole.DebugWriteLine("LisaFS plugin", "ExtentFile[{0}].password = {1}", fileId,
CurrentEncoding.GetString(file.password));
DicConsole.DebugWriteLine("LisaFS plugin", "ExtentFile[{0}].unknown7 = 0x{1:X2}{2:X2}{3:X2}",
fileId, file.unknown7[0], file.unknown7[1], file.unknown7[2]);
DicConsole.DebugWriteLine("LisaFS plugin", "ExtentFile[{0}].unknown7 = 0x{1:X2}{2:X2}{3:X2}", fileId,
file.unknown7[0], file.unknown7[1], file.unknown7[2]);
DicConsole.DebugWriteLine("LisaFS plugin", "ExtentFile[{0}].overhead = {1}", fileId, file.overhead);
DicConsole.DebugWriteLine("LisaFS plugin",
"ExtentFile[{0}].unknown8 = 0x{1:X2}{2:X2}{3:X2}{4:X2}{5:X2}{6:X2}{7:X2}{8:X2}{9:X2}" +
"{10:X2}{11:X2}{12:X2}{13:X2}{14:X2}{15:X2}{16:X2}", fileId,
file.unknown8[0], file.unknown8[1], file.unknown8[2], file.unknown8[3],
file.unknown8[4], file.unknown8[5], file.unknown8[6], file.unknown8[7],
file.unknown8[8], file.unknown8[9], file.unknown8[10], file.unknown8[11],
file.unknown8[12], file.unknown8[13], file.unknown8[14],
file.unknown8[15]);
"{10:X2}{11:X2}{12:X2}{13:X2}{14:X2}{15:X2}{16:X2}", fileId, file.unknown8[0],
file.unknown8[1], file.unknown8[2], file.unknown8[3], file.unknown8[4],
file.unknown8[5], file.unknown8[6], file.unknown8[7], file.unknown8[8],
file.unknown8[9], file.unknown8[10], file.unknown8[11], file.unknown8[12],
file.unknown8[13], file.unknown8[14], file.unknown8[15]);
DicConsole.DebugWriteLine("LisaFS plugin", "ExtentFile[{0}].length = {1}", fileId, file.length);
DicConsole.DebugWriteLine("LisaFS plugin", "ExtentFile[{0}].unknown9 = 0x{1:X8}", fileId,
file.unknown9);
DicConsole.DebugWriteLine("LisaFS plugin", "ExtentFile[{0}].unknown9 = 0x{1:X8}", fileId, file.unknown9);
for(int ext = 0; ext < file.extents.Length; ext++)
{
DicConsole.DebugWriteLine("LisaFS plugin", "ExtentFile[{0}].extents[{1}].start = {2}", fileId,
ext, file.extents[ext].start);
DicConsole.DebugWriteLine("LisaFS plugin", "ExtentFile[{0}].extents[{1}].length = {2}", fileId,
ext, file.extents[ext].length);
DicConsole.DebugWriteLine("LisaFS plugin", "ExtentFile[{0}].extents[{1}].start = {2}", fileId, ext,
file.extents[ext].start);
DicConsole.DebugWriteLine("LisaFS plugin", "ExtentFile[{0}].extents[{1}].length = {2}", fileId, ext,
file.extents[ext].length);
}
DicConsole.DebugWriteLine("LisaFS plugin", "ExtentFile[{0}].unknown10 = 0x{1:X4}", fileId,
file.unknown10);
DicConsole.DebugWriteLine("LisaFS plugin", "ExtentFile[{0}].unknown10 = 0x{1:X4}", fileId, file.unknown10);
printedExtents.Add(fileId);
@@ -263,7 +248,7 @@ namespace DiscImageChef.Filesystems.LisaFS
}
/// <summary>
/// Reads all the S-Records and caches it
/// Reads all the S-Records and caches it
/// </summary>
Errno ReadSRecords()
{
@@ -276,15 +261,13 @@ namespace DiscImageChef.Filesystems.LisaFS
srecords = new SRecord[sectors.Length / 14];
for(int s = 0; s < srecords.Length; s++)
{
srecords[s] = new SRecord
{
{
extent_ptr = BigEndianBitConverter.ToUInt32(sectors, 0x00 + 14 * s),
unknown = BigEndianBitConverter.ToUInt32(sectors, 0x04 + 14 * s),
filesize = BigEndianBitConverter.ToUInt32(sectors, 0x08 + 14 * s),
flags = BigEndianBitConverter.ToUInt16(sectors, 0x0C + 14 * s)
};
}
return Errno.NoError;
}

View File

@@ -161,7 +161,8 @@ namespace DiscImageChef.Filesystems.LisaFS
buf = null;
if(!mounted || !debug) return Errno.AccessDenied;
if(fileId > 4 || fileId <= 0) if(fileId != FILEID_BOOT_SIGNED && fileId != FILEID_LOADER_SIGNED) return Errno.InvalidArgument;
if(fileId > 4 || fileId <= 0)
if(fileId != FILEID_BOOT_SIGNED && fileId != FILEID_LOADER_SIGNED) return Errno.InvalidArgument;
if(systemFileCache.TryGetValue(fileId, out buf) && !tags) return Errno.NoError;
@@ -346,7 +347,8 @@ namespace DiscImageChef.Filesystems.LisaFS
if(!tags)
{
if(fileSizeCache.TryGetValue(fileId, out int realSize)) if(realSize > temp.Length) DicConsole.ErrorWriteLine("File {0} gets truncated.", fileId);
if(fileSizeCache.TryGetValue(fileId, out int realSize))
if(realSize > temp.Length) DicConsole.ErrorWriteLine("File {0} gets truncated.", fileId);
buf = temp;
fileCache.Add(fileId, buf);

View File

@@ -61,7 +61,8 @@ namespace DiscImageChef.Filesystems.LisaFS
// LisaOS searches sectors until tag tells MDDF resides there, so we'll search 100 sectors
for(int i = 0; i < 100; i++)
{
DecodeTag(imagePlugin.ReadSectorTag((ulong)i, SectorTagType.AppleSectorTag), out LisaTag.PriamTag searchTag);
DecodeTag(imagePlugin.ReadSectorTag((ulong)i, SectorTagType.AppleSectorTag),
out LisaTag.PriamTag searchTag);
DicConsole.DebugWriteLine("LisaFS plugin", "Sector {0}, file ID 0x{1:X4}", i, searchTag.FileId);
@@ -137,7 +138,8 @@ namespace DiscImageChef.Filesystems.LisaFS
// LisaOS searches sectors until tag tells MDDF resides there, so we'll search 100 sectors
for(int i = 0; i < 100; i++)
{
DecodeTag(imagePlugin.ReadSectorTag((ulong)i, SectorTagType.AppleSectorTag), out LisaTag.PriamTag searchTag);
DecodeTag(imagePlugin.ReadSectorTag((ulong)i, SectorTagType.AppleSectorTag),
out LisaTag.PriamTag searchTag);
DicConsole.DebugWriteLine("LisaFS plugin", "Sector {0}, file ID 0x{1:X4}", i, searchTag.FileId);
@@ -307,11 +309,10 @@ namespace DiscImageChef.Filesystems.LisaFS
sb.AppendFormat("Master copy ID: 0x{0:X8}", infoMddf.master_copy_id).AppendLine();
sb.AppendFormat("Volume is number {0} of {1}", infoMddf.volnum, infoMddf.vol_sequence)
.AppendLine();
sb.AppendFormat("Volume is number {0} of {1}", infoMddf.volnum, infoMddf.vol_sequence).AppendLine();
sb.AppendFormat("Serial number of Lisa computer that created this volume: {0}",
infoMddf.machine_id).AppendLine();
sb.AppendFormat("Serial number of Lisa computer that created this volume: {0}", infoMddf.machine_id)
.AppendLine();
sb.AppendFormat("Serial number of Lisa computer that can use this volume's software {0}",
infoMddf.serialization).AppendLine();
@@ -341,8 +342,7 @@ namespace DiscImageChef.Filesystems.LisaFS
infoMddf.srec_ptr + infoMddf.mddf_block + beforeMddf, infoMddf.srec_len)
.AppendLine();
if(infoMddf.vol_left_mounted == 0) sb.AppendLine("Volume is clean");
else sb.AppendLine("Volume is dirty");
sb.AppendLine(infoMddf.vol_left_mounted == 0 ? "Volume is clean" : "Volume is dirty");
information = sb.ToString();

View File

@@ -43,31 +43,14 @@ namespace DiscImageChef.Filesystems.LisaFS
// Variable names from Lisa API
public partial class LisaFS : Filesystem
{
bool mounted;
bool debug;
readonly ImagePlugin device;
bool debug;
int devTagSize;
MDDF mddf;
ulong volumePrefix;
int devTagSize;
bool mounted;
SRecord[] srecords;
#region Caches
/// <summary>Caches Extents Files</summary>
Dictionary<short, ExtentFile> extentCache;
/// <summary>Caches system files</summary>
Dictionary<short, byte[]> systemFileCache;
/// <summary>Caches user files files</summary>
Dictionary<short, byte[]> fileCache;
/// <summary>Caches catalogs</summary>
List<CatalogEntry> catalogCache;
/// <summary>Caches file size</summary>
Dictionary<short, int> fileSizeCache;
/// <summary>Lists Extents Files already printed in debug mode to not repeat them</summary>
List<short> printedExtents;
/// <summary>Caches the creation times for subdirectories as to not have to traverse the Catalog File on each stat</summary>
Dictionary<short, DateTime> directoryDtcCache;
#endregion Caches
ulong volumePrefix;
public LisaFS()
{
@@ -90,5 +73,22 @@ namespace DiscImageChef.Filesystems.LisaFS
PluginUuid = new Guid("7E6034D1-D823-4248-A54D-239742B28391");
CurrentEncoding = new LisaRoman();
}
#region Caches
/// <summary>Caches Extents Files</summary>
Dictionary<short, ExtentFile> extentCache;
/// <summary>Caches system files</summary>
Dictionary<short, byte[]> systemFileCache;
/// <summary>Caches user files files</summary>
Dictionary<short, byte[]> fileCache;
/// <summary>Caches catalogs</summary>
List<CatalogEntry> catalogCache;
/// <summary>Caches file size</summary>
Dictionary<short, int> fileSizeCache;
/// <summary>Lists Extents Files already printed in debug mode to not repeat them</summary>
List<short> printedExtents;
/// <summary>Caches the creation times for subdirectories as to not have to traverse the Catalog File on each stat</summary>
Dictionary<short, DateTime> directoryDtcCache;
#endregion Caches
}
}

View File

@@ -37,11 +37,11 @@ namespace DiscImageChef.Filesystems.LisaFS
public partial class LisaFS
{
/// <summary>
/// The MDDF is the most import block on a Lisa FS volume.
/// It describes the volume and its contents.
/// On initialization the memory where it resides is not emptied
/// so it tends to contain a lot of garbage. This has difficulted
/// its reverse engineering.
/// The MDDF is the most import block on a Lisa FS volume.
/// It describes the volume and its contents.
/// On initialization the memory where it resides is not emptied
/// so it tends to contain a lot of garbage. This has difficulted
/// its reverse engineering.
/// </summary>
struct MDDF
{
@@ -209,10 +209,10 @@ namespace DiscImageChef.Filesystems.LisaFS
}
/// <summary>
/// An entry in the catalog from V3.
/// The first entry is bigger than the rest, may be a header, I have not needed any of its values so I just ignored it.
/// Each catalog is divided in 4-sector blocks, and if it needs more than a block there are previous and next block
/// pointers, effectively making the V3 catalog a double-linked list. Garbage is not zeroed.
/// An entry in the catalog from V3.
/// The first entry is bigger than the rest, may be a header, I have not needed any of its values so I just ignored it.
/// Each catalog is divided in 4-sector blocks, and if it needs more than a block there are previous and next block
/// pointers, effectively making the V3 catalog a double-linked list. Garbage is not zeroed.
/// </summary>
struct CatalogEntry
{
@@ -225,11 +225,11 @@ namespace DiscImageChef.Filesystems.LisaFS
/// <summary>0x23, null-termination</summary>
public byte terminator;
/// <summary>
/// At 0x24
/// 0x01 here for subdirectories, entries 48 bytes long
/// 0x03 here for entries 64 bytes long
/// 0x08 here for entries 78 bytes long
/// This is incomplete, may fail, mostly works...
/// At 0x24
/// 0x01 here for subdirectories, entries 48 bytes long
/// 0x03 here for entries 64 bytes long
/// 0x08 here for entries 78 bytes long
/// This is incomplete, may fail, mostly works...
/// </summary>
public byte fileType;
/// <summary>0x25, lot of values found here, unknown</summary>
@@ -249,7 +249,7 @@ namespace DiscImageChef.Filesystems.LisaFS
}
/// <summary>
/// An extent indicating a start and a run of sectors.
/// An extent indicating a start and a run of sectors.
/// </summary>
struct Extent
{
@@ -258,12 +258,12 @@ namespace DiscImageChef.Filesystems.LisaFS
}
/// <summary>
/// The Extents File. There is one Extents File per each file stored on disk.
/// The file ID present on the sectors tags for the Extents File is the negated
/// value of the file ID it represents. e.g. file = 5 (0x0005) extents = -5 (0xFFFB)
/// It spans a single sector on V2 and V3 but 2 sectors on V1.
/// It contains all information about a file, and is indexed in the S-Records file.
/// It also contains the label. Garbage is zeroed.
/// The Extents File. There is one Extents File per each file stored on disk.
/// The file ID present on the sectors tags for the Extents File is the negated
/// value of the file ID it represents. e.g. file = 5 (0x0005) extents = -5 (0xFFFB)
/// It spans a single sector on V2 and V3 but 2 sectors on V1.
/// It contains all information about a file, and is indexed in the S-Records file.
/// It also contains the label. Garbage is zeroed.
/// </summary>
struct ExtentFile
{
@@ -335,29 +335,38 @@ namespace DiscImageChef.Filesystems.LisaFS
public int length;
/// <summary>0x84, 0x204 in v1, unknown</summary>
public int unknown9;
/// <summary>0x88, 0x208 in v1, extents, can contain up to 41 extents (85 in v1), dunno LisaOS maximum (never seen more than 3)</summary>
/// <summary>
/// 0x88, 0x208 in v1, extents, can contain up to 41 extents (85 in v1), dunno LisaOS maximum (never seen more
/// than 3)
/// </summary>
public Extent[] extents;
/// <summary>0x17E, unknown, empty, padding?</summary>
public short unknown10;
/// <summary>
/// At 0x180, this is the label.
/// While 1982 pre-release documentation says the label can be up to 448 bytes, v1 onward only have space for a 128 bytes one.
/// Any application can write whatever they want in the label, however, Lisa Office uses it to store its own information, something
/// that will effectively overwrite any information a user application wrote there.
/// The information written here by Lisa Office is like the information Finder writes in the FinderInfo structures, plus
/// the non-unique name that is shown on the GUI. For this reason I called it LisaInfo.
/// I have not tried to reverse engineer it.
/// At 0x180, this is the label.
/// While 1982 pre-release documentation says the label can be up to 448 bytes, v1 onward only have space for a 128
/// bytes one.
/// Any application can write whatever they want in the label, however, Lisa Office uses it to store its own
/// information, something
/// that will effectively overwrite any information a user application wrote there.
/// The information written here by Lisa Office is like the information Finder writes in the FinderInfo structures,
/// plus
/// the non-unique name that is shown on the GUI. For this reason I called it LisaInfo.
/// I have not tried to reverse engineer it.
/// </summary>
public byte[] LisaInfo;
}
/// <summary>
/// The S-Records File is a hashtable of S-Records, where the hash is the file ID they belong to.
/// The S-Records File cannot be fragmented or grown, and it can easily become full before the 32766 file IDs are exhausted.
/// Each S-Record entry contains a block pointer to the Extents File that correspond to that file ID as well as the real file size,
/// the only important information about a file that's not inside the Extents File.
/// It also contains a low value (less than 0x200) variable field of unknown meaning and another one that seems to be flags,
/// with values like 0, 1, 3 and 5.
/// The S-Records File is a hashtable of S-Records, where the hash is the file ID they belong to.
/// The S-Records File cannot be fragmented or grown, and it can easily become full before the 32766 file IDs are
/// exhausted.
/// Each S-Record entry contains a block pointer to the Extents File that correspond to that file ID as well as the
/// real file size,
/// the only important information about a file that's not inside the Extents File.
/// It also contains a low value (less than 0x200) variable field of unknown meaning and another one that seems to be
/// flags,
/// with values like 0, 1, 3 and 5.
/// </summary>
struct SRecord
{
@@ -372,13 +381,13 @@ namespace DiscImageChef.Filesystems.LisaFS
}
/// <summary>
/// The catalog entry for the V1 and V2 volume formats.
/// It merely contains the file name, type and ID, plus a few (mostly empty) unknown fields.
/// Contrary to V3, it has no header and instead of being a double-linked list it is fragmented using an Extents File.
/// The Extents File position for the root catalog is then stored in the S-Records File.
/// Its entries are not filed sequentially denoting some kind of in-memory structure while at the same time
/// forcing LisaOS to read the whole catalog. That or I missed the pointers.
/// Empty entries just contain a 0-len filename. Garbage is not zeroed.
/// The catalog entry for the V1 and V2 volume formats.
/// It merely contains the file name, type and ID, plus a few (mostly empty) unknown fields.
/// Contrary to V3, it has no header and instead of being a double-linked list it is fragmented using an Extents File.
/// The Extents File position for the root catalog is then stored in the S-Records File.
/// Its entries are not filed sequentially denoting some kind of in-memory structure while at the same time
/// forcing LisaOS to read the whole catalog. That or I missed the pointers.
/// Empty entries just contain a 0-len filename. Garbage is not zeroed.
/// </summary>
struct CatalogEntryV2
{

View File

@@ -42,7 +42,7 @@ namespace DiscImageChef.Filesystems.LisaFS
public partial class LisaFS
{
/// <summary>
/// Mounts an Apple Lisa filesystem
/// Mounts an Apple Lisa filesystem
/// </summary>
public override Errno Mount()
{
@@ -50,7 +50,7 @@ namespace DiscImageChef.Filesystems.LisaFS
}
/// <summary>
/// Mounts an Apple Lisa filesystem
/// Mounts an Apple Lisa filesystem
/// </summary>
public override Errno Mount(bool debug)
{
@@ -319,7 +319,7 @@ namespace DiscImageChef.Filesystems.LisaFS
}
/// <summary>
/// Umounts this Lisa filesystem
/// Umounts this Lisa filesystem
/// </summary>
public override Errno Unmount()
{
@@ -339,7 +339,7 @@ namespace DiscImageChef.Filesystems.LisaFS
}
/// <summary>
/// Gets information about the mounted volume.
/// Gets information about the mounted volume.
/// </summary>
/// <param name="stat">Information about the mounted volume.</param>
public override Errno StatFs(ref FileSystemInfo stat)

View File

@@ -41,7 +41,7 @@ namespace DiscImageChef.Filesystems.LisaFS
public partial class LisaFS
{
/// <summary>
/// Lists all extended attributes, alternate data streams and forks of the given file.
/// Lists all extended attributes, alternate data streams and forks of the given file.
/// </summary>
/// <returns>Error number.</returns>
/// <param name="path">Path.</param>
@@ -55,7 +55,7 @@ namespace DiscImageChef.Filesystems.LisaFS
}
/// <summary>
/// Reads an extended attribute, alternate data stream or fork from the given file.
/// Reads an extended attribute, alternate data stream or fork from the given file.
/// </summary>
/// <returns>Error number.</returns>
/// <param name="path">File path.</param>
@@ -70,7 +70,7 @@ namespace DiscImageChef.Filesystems.LisaFS
}
/// <summary>
/// Lists special Apple Lisa filesystem features as extended attributes
/// Lists special Apple Lisa filesystem features as extended attributes
/// </summary>
/// <returns>Error number.</returns>
/// <param name="fileId">File identifier.</param>
@@ -125,7 +125,7 @@ namespace DiscImageChef.Filesystems.LisaFS
}
/// <summary>
/// Lists special Apple Lisa filesystem features as extended attributes
/// Lists special Apple Lisa filesystem features as extended attributes
/// </summary>
/// <returns>Error number.</returns>
/// <param name="fileId">File identifier.</param>
@@ -161,7 +161,8 @@ namespace DiscImageChef.Filesystems.LisaFS
if(error != Errno.NoError) return error;
switch(xattr) {
switch(xattr)
{
case "com.apple.lisa.password" when file.password_valid > 0:
buf = new byte[8];
Array.Copy(file.password, 0, buf, 0, 8);
@@ -184,7 +185,7 @@ namespace DiscImageChef.Filesystems.LisaFS
}
/// <summary>
/// Decodes a sector tag. Not tested with 24-byte tags.
/// Decodes a sector tag. Not tested with 24-byte tags.
/// </summary>
/// <returns>Error number.</returns>
/// <param name="tag">Sector tag.</param>