Code cleanup.

This commit is contained in:
2018-06-22 08:08:38 +01:00
parent 82f474c7e3
commit 88da8fc019
581 changed files with 22423 additions and 20839 deletions

View File

@@ -44,11 +44,11 @@ namespace DiscImageChef.Filesystems
// This may be missing fields, or not, I don't know russian so any help is appreciated
public class AODOS : IFilesystem
{
readonly byte[] AODOSIdentifier = {0x20, 0x41, 0x4F, 0x2D, 0x44, 0x4F, 0x53, 0x20};
public FileSystemType XmlFsType { get; private set; }
public string Name => "Alexander Osipov DOS file system";
public Guid Id => new Guid("668E5039-9DDD-442A-BE1B-A315D6E38E26");
public Encoding Encoding { get; private set; }
readonly byte[] AODOSIdentifier = {0x20, 0x41, 0x4F, 0x2D, 0x44, 0x4F, 0x53, 0x20};
public FileSystemType XmlFsType { get; private set; }
public string Name => "Alexander Osipov DOS file system";
public Guid Id => new Guid("668E5039-9DDD-442A-BE1B-A315D6E38E26");
public Encoding Encoding { get; private set; }
public bool Identify(IMediaImage imagePlugin, Partition partition)
{
@@ -61,9 +61,9 @@ namespace DiscImageChef.Filesystems
// Does AO-DOS support any other kind of disk?
if(imagePlugin.Info.Sectors != 800 && imagePlugin.Info.Sectors != 1600) return false;
byte[] sector = imagePlugin.ReadSector(0);
AODOS_BootBlock bb = new AODOS_BootBlock();
IntPtr bbPtr = Marshal.AllocHGlobal(Marshal.SizeOf(bb));
byte[] sector = imagePlugin.ReadSector(0);
AODOS_BootBlock bb = new AODOS_BootBlock();
IntPtr bbPtr = Marshal.AllocHGlobal(Marshal.SizeOf(bb));
Marshal.Copy(sector, 0, bbPtr, Marshal.SizeOf(bb));
bb = (AODOS_BootBlock)Marshal.PtrToStructure(bbPtr, typeof(AODOS_BootBlock));
Marshal.FreeHGlobal(bbPtr);
@@ -72,12 +72,12 @@ namespace DiscImageChef.Filesystems
}
public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
Encoding encoding)
Encoding encoding)
{
Encoding = Encoding.GetEncoding("koi8-r");
byte[] sector = imagePlugin.ReadSector(0);
AODOS_BootBlock bb = new AODOS_BootBlock();
IntPtr bbPtr = Marshal.AllocHGlobal(Marshal.SizeOf(bb));
byte[] sector = imagePlugin.ReadSector(0);
AODOS_BootBlock bb = new AODOS_BootBlock();
IntPtr bbPtr = Marshal.AllocHGlobal(Marshal.SizeOf(bb));
Marshal.Copy(sector, 0, bbPtr, Marshal.SizeOf(bb));
bb = (AODOS_BootBlock)Marshal.PtrToStructure(bbPtr, typeof(AODOS_BootBlock));
Marshal.FreeHGlobal(bbPtr);
@@ -88,15 +88,15 @@ namespace DiscImageChef.Filesystems
XmlFsType = new FileSystemType
{
Type = "Alexander Osipov DOS file system",
Clusters = (long)imagePlugin.Info.Sectors,
ClusterSize = (int)imagePlugin.Info.SectorSize,
Files = bb.files,
FilesSpecified = true,
FreeClusters = (long)(imagePlugin.Info.Sectors - bb.usedSectors),
Type = "Alexander Osipov DOS file system",
Clusters = (long)imagePlugin.Info.Sectors,
ClusterSize = (int)imagePlugin.Info.SectorSize,
Files = bb.files,
FilesSpecified = true,
FreeClusters = (long)(imagePlugin.Info.Sectors - bb.usedSectors),
FreeClustersSpecified = true,
VolumeName = StringHandlers.SpacePaddedToString(bb.volumeLabel, Encoding),
Bootable = true
VolumeName = StringHandlers.SpacePaddedToString(bb.volumeLabel, Encoding),
Bootable = true
};
sbInformation.AppendFormat("{0} files on volume", bb.files).AppendLine();
@@ -125,11 +125,13 @@ namespace DiscImageChef.Filesystems
/// <summary>
/// " AO-DOS "
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] public byte[] identifier;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public byte[] identifier;
/// <summary>
/// Volume label
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)] public byte[] volumeLabel;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)]
public byte[] volumeLabel;
/// <summary>
/// How many files are present in disk
/// </summary>

View File

@@ -42,18 +42,18 @@ namespace DiscImageChef.Filesystems
public class APFS : IFilesystem
{
const uint APFS_CONTAINER_MAGIC = 0x4253584E; // "NXSB"
const uint APFS_VOLUME_MAGIC = 0x42535041; // "APSB"
const uint APFS_VOLUME_MAGIC = 0x42535041; // "APSB"
public FileSystemType XmlFsType { get; private set; }
public Encoding Encoding { get; private set; }
public string Name => "Apple File System";
public Guid Id => new Guid("A4060F9D-2909-42E2-9D95-DB31FA7EA797");
public Encoding Encoding { get; private set; }
public string Name => "Apple File System";
public Guid Id => new Guid("A4060F9D-2909-42E2-9D95-DB31FA7EA797");
public bool Identify(IMediaImage imagePlugin, Partition partition)
{
if(partition.Start >= partition.End) return false;
byte[] sector = imagePlugin.ReadSector(partition.Start);
byte[] sector = imagePlugin.ReadSector(partition.Start);
ApfsContainerSuperBlock nxSb;
try
@@ -69,16 +69,16 @@ namespace DiscImageChef.Filesystems
}
public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
Encoding encoding)
Encoding encoding)
{
Encoding = Encoding.UTF8;
StringBuilder sbInformation = new StringBuilder();
XmlFsType = new FileSystemType();
XmlFsType = new FileSystemType();
information = "";
if(partition.Start >= partition.End) return;
byte[] sector = imagePlugin.ReadSector(partition.Start);
byte[] sector = imagePlugin.ReadSector(partition.Start);
ApfsContainerSuperBlock nxSb;
try
@@ -102,10 +102,10 @@ namespace DiscImageChef.Filesystems
XmlFsType = new FileSystemType
{
Bootable = false,
Clusters = (long)nxSb.containerBlocks,
Bootable = false,
Clusters = (long)nxSb.containerBlocks,
ClusterSize = (int)nxSb.blockSize,
Type = "Apple File System"
Type = "Apple File System"
};
}
@@ -116,8 +116,8 @@ namespace DiscImageChef.Filesystems
public ulong unknown2;
public ulong unknown3; // Varies by 1 between copies of the superblock
public ulong unknown4;
public uint magic;
public uint blockSize;
public uint magic;
public uint blockSize;
public ulong containerBlocks;
}
}

View File

@@ -78,9 +78,9 @@ namespace DiscImageChef.Filesystems
const uint OLD_DIR_MAGIC = 0x6F677548;
public FileSystemType XmlFsType { get; private set; }
public string Name => "Acorn Advanced Disc Filing System";
public Guid Id => new Guid("BAFC1E50-9C64-4CD3-8400-80628CC27AFA");
public Encoding Encoding { get; private set; }
public string Name => "Acorn Advanced Disc Filing System";
public Guid Id => new Guid("BAFC1E50-9C64-4CD3-8400-80628CC27AFA");
public Encoding Encoding { get; private set; }
// TODO: BBC Master hard disks are untested...
public bool Identify(IMediaImage imagePlugin, Partition partition)
@@ -88,11 +88,11 @@ namespace DiscImageChef.Filesystems
if(partition.Start >= partition.End) return false;
ulong sbSector;
uint sectorsToRead;
uint sectorsToRead;
if(imagePlugin.Info.SectorSize < 256) return false;
byte[] sector;
byte[] sector;
GCHandle ptr;
// ADFS-S, ADFS-M, ADFS-L, ADFS-D without partitions
@@ -111,7 +111,7 @@ namespace DiscImageChef.Filesystems
(OldMapSector1)Marshal.PtrToStructure(ptr.AddrOfPinnedObject(), typeof(OldMapSector1));
DicConsole.DebugWriteLine("ADFS Plugin", "oldMap0.checksum = {0}", oldMap0.checksum);
DicConsole.DebugWriteLine("ADFS Plugin", "oldChk0 = {0}", oldChk0);
DicConsole.DebugWriteLine("ADFS Plugin", "oldChk0 = {0}", oldChk0);
// According to documentation map1 MUST start on sector 1. On ADFS-D it starts at 0x100, not on sector 1 (0x400)
if(oldMap0.checksum == oldChk0 && oldMap1.checksum != oldChk1 && sector.Length >= 512)
@@ -120,28 +120,29 @@ namespace DiscImageChef.Filesystems
byte[] tmp = new byte[256];
Array.Copy(sector, 256, tmp, 0, 256);
oldChk1 = AcornMapChecksum(tmp, 255);
ptr = GCHandle.Alloc(tmp, GCHandleType.Pinned);
ptr = GCHandle.Alloc(tmp, GCHandleType.Pinned);
oldMap1 = (OldMapSector1)Marshal.PtrToStructure(ptr.AddrOfPinnedObject(), typeof(OldMapSector1));
}
DicConsole.DebugWriteLine("ADFS Plugin", "oldMap1.checksum = {0}", oldMap1.checksum);
DicConsole.DebugWriteLine("ADFS Plugin", "oldChk1 = {0}", oldChk1);
DicConsole.DebugWriteLine("ADFS Plugin", "oldChk1 = {0}", oldChk1);
if(oldMap0.checksum == oldChk0 && oldMap1.checksum == oldChk1 && oldMap0.checksum != 0 &&
oldMap1.checksum != 0)
{
sbSector = OLD_DIRECTORY_LOCATION / imagePlugin.Info.SectorSize;
sectorsToRead = OLD_DIRECTORY_SIZE / imagePlugin.Info.SectorSize;
if(OLD_DIRECTORY_SIZE % imagePlugin.Info.SectorSize > 0) sectorsToRead++;
sbSector = OLD_DIRECTORY_LOCATION / imagePlugin.Info.SectorSize;
sectorsToRead = OLD_DIRECTORY_SIZE / imagePlugin.Info.SectorSize;
if(OLD_DIRECTORY_SIZE % imagePlugin.Info.SectorSize > 0) sectorsToRead++;
sector = imagePlugin.ReadSectors(sbSector, sectorsToRead);
if(sector.Length > OLD_DIRECTORY_SIZE)
{
byte[] tmp = new byte[OLD_DIRECTORY_SIZE];
Array.Copy(sector, 0, tmp, 0, OLD_DIRECTORY_SIZE - 53);
Array.Copy(sector, sector.Length - 54, tmp, OLD_DIRECTORY_SIZE - 54, 53);
Array.Copy(sector, sector.Length - 54, tmp, OLD_DIRECTORY_SIZE - 54, 53);
sector = tmp;
}
ptr = GCHandle.Alloc(sector, GCHandleType.Pinned);
OldDirectory oldRoot =
(OldDirectory)Marshal.PtrToStructure(ptr.AddrOfPinnedObject(), typeof(OldDirectory));
@@ -158,21 +159,22 @@ namespace DiscImageChef.Filesystems
oldRoot.header.magic == NEW_DIR_MAGIC && oldRoot.tail.magic == NEW_DIR_MAGIC) return true;
// RISC OS says the old directory can't be in the new location, hard disks created by RISC OS 3.10 do that...
sbSector = NEW_DIRECTORY_LOCATION / imagePlugin.Info.SectorSize;
sectorsToRead = NEW_DIRECTORY_SIZE / imagePlugin.Info.SectorSize;
if(NEW_DIRECTORY_SIZE % imagePlugin.Info.SectorSize > 0) sectorsToRead++;
sbSector = NEW_DIRECTORY_LOCATION / imagePlugin.Info.SectorSize;
sectorsToRead = NEW_DIRECTORY_SIZE / imagePlugin.Info.SectorSize;
if(NEW_DIRECTORY_SIZE % imagePlugin.Info.SectorSize > 0) sectorsToRead++;
sector = imagePlugin.ReadSectors(sbSector, sectorsToRead);
if(sector.Length > OLD_DIRECTORY_SIZE)
{
byte[] tmp = new byte[OLD_DIRECTORY_SIZE];
Array.Copy(sector, 0, tmp, 0, OLD_DIRECTORY_SIZE - 53);
Array.Copy(sector, sector.Length - 54, tmp, OLD_DIRECTORY_SIZE - 54, 53);
Array.Copy(sector, sector.Length - 54, tmp, OLD_DIRECTORY_SIZE - 54, 53);
sector = tmp;
}
ptr = GCHandle.Alloc(sector, GCHandleType.Pinned);
ptr = GCHandle.Alloc(sector, GCHandleType.Pinned);
oldRoot = (OldDirectory)Marshal.PtrToStructure(ptr.AddrOfPinnedObject(), typeof(OldDirectory));
dirChk = AcornDirectoryChecksum(sector, (int)OLD_DIRECTORY_SIZE - 1);
dirChk = AcornDirectoryChecksum(sector, (int)OLD_DIRECTORY_SIZE - 1);
DicConsole.DebugWriteLine("ADFS Plugin", "oldRoot.header.magic at 0x400 = {0}",
oldRoot.header.magic);
@@ -191,20 +193,20 @@ namespace DiscImageChef.Filesystems
sector = imagePlugin.ReadSector(partition.Start);
byte newChk = NewMapChecksum(sector);
DicConsole.DebugWriteLine("ADFS Plugin", "newChk = {0}", newChk);
DicConsole.DebugWriteLine("ADFS Plugin", "newChk = {0}", newChk);
DicConsole.DebugWriteLine("ADFS Plugin", "map.zoneChecksum = {0}", sector[0]);
sbSector = BOOT_BLOCK_LOCATION / imagePlugin.Info.SectorSize;
sectorsToRead = BOOT_BLOCK_SIZE / imagePlugin.Info.SectorSize;
if(BOOT_BLOCK_SIZE % imagePlugin.Info.SectorSize > 0) sectorsToRead++;
sbSector = BOOT_BLOCK_LOCATION / imagePlugin.Info.SectorSize;
sectorsToRead = BOOT_BLOCK_SIZE / imagePlugin.Info.SectorSize;
if(BOOT_BLOCK_SIZE % imagePlugin.Info.SectorSize > 0) sectorsToRead++;
if(sbSector + partition.Start + sectorsToRead >= partition.End) return false;
byte[] bootSector = imagePlugin.ReadSectors(sbSector + partition.Start, sectorsToRead);
int bootChk = 0;
byte[] bootSector = imagePlugin.ReadSectors(sbSector + partition.Start, sectorsToRead);
int bootChk = 0;
for(int i = 0; i < 0x1FF; i++) bootChk = (bootChk & 0xFF) + (bootChk >> 8) + bootSector[i];
DicConsole.DebugWriteLine("ADFS Plugin", "bootChk = {0}", bootChk);
DicConsole.DebugWriteLine("ADFS Plugin", "bootChk = {0}", bootChk);
DicConsole.DebugWriteLine("ADFS Plugin", "bBlock.checksum = {0}", bootSector[0x1FF]);
if(newChk == sector[0] && newChk != 0)
@@ -223,10 +225,10 @@ namespace DiscImageChef.Filesystems
}
else return false;
DicConsole.DebugWriteLine("ADFS Plugin", "drSb.log2secsize = {0}", drSb.log2secsize);
DicConsole.DebugWriteLine("ADFS Plugin", "drSb.idlen = {0}", drSb.idlen);
DicConsole.DebugWriteLine("ADFS Plugin", "drSb.log2secsize = {0}", drSb.log2secsize);
DicConsole.DebugWriteLine("ADFS Plugin", "drSb.idlen = {0}", drSb.idlen);
DicConsole.DebugWriteLine("ADFS Plugin", "drSb.disc_size_high = {0}", drSb.disc_size_high);
DicConsole.DebugWriteLine("ADFS Plugin", "drSb.disc_size = {0}", drSb.disc_size);
DicConsole.DebugWriteLine("ADFS Plugin", "drSb.disc_size = {0}", drSb.disc_size);
DicConsole.DebugWriteLine("ADFS Plugin", "IsNullOrEmpty(drSb.reserved) = {0}",
ArrayHelpers.ArrayIsNullOrEmpty(drSb.reserved));
@@ -249,18 +251,18 @@ namespace DiscImageChef.Filesystems
// TODO: Support big directories (ADFS-G?)
// TODO: Find the real freemap on volumes with DiscRecord, as DiscRecord's discid may be empty but this one isn't
public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
Encoding encoding)
Encoding encoding)
{
Encoding = encoding ?? Encoding.GetEncoding("iso-8859-1");
StringBuilder sbInformation = new StringBuilder();
XmlFsType = new FileSystemType();
XmlFsType = new FileSystemType();
information = "";
ulong sbSector;
byte[] sector;
uint sectorsToRead;
ulong sbSector;
byte[] sector;
uint sectorsToRead;
GCHandle ptr;
ulong bytes;
ulong bytes;
// ADFS-S, ADFS-M, ADFS-L, ADFS-D without partitions
if(partition.Start == 0)
@@ -284,7 +286,7 @@ namespace DiscImageChef.Filesystems
byte[] tmp = new byte[256];
Array.Copy(sector, 256, tmp, 0, 256);
oldChk1 = AcornMapChecksum(tmp, 255);
ptr = GCHandle.Alloc(tmp, GCHandleType.Pinned);
ptr = GCHandle.Alloc(tmp, GCHandleType.Pinned);
oldMap1 = (OldMapSector1)Marshal.PtrToStructure(ptr.AddrOfPinnedObject(), typeof(OldMapSector1));
}
@@ -295,32 +297,33 @@ namespace DiscImageChef.Filesystems
byte[] namebytes = new byte[10];
for(int i = 0; i < 5; i++)
{
namebytes[i * 2] = oldMap0.name[i];
namebytes[i * 2] = oldMap0.name[i];
namebytes[i * 2 + 1] = oldMap1.name[i];
}
XmlFsType = new FileSystemType
{
Bootable = oldMap1.boot != 0, // Or not?
Clusters = (long)(bytes / imagePlugin.Info.SectorSize),
Bootable = oldMap1.boot != 0, // Or not?
Clusters = (long)(bytes / imagePlugin.Info.SectorSize),
ClusterSize = (int)imagePlugin.Info.SectorSize,
Type = "Acorn Advanced Disc Filing System"
Type = "Acorn Advanced Disc Filing System"
};
if(ArrayHelpers.ArrayIsNullOrEmpty(namebytes))
{
sbSector = OLD_DIRECTORY_LOCATION / imagePlugin.Info.SectorSize;
sectorsToRead = OLD_DIRECTORY_SIZE / imagePlugin.Info.SectorSize;
if(OLD_DIRECTORY_SIZE % imagePlugin.Info.SectorSize > 0) sectorsToRead++;
sbSector = OLD_DIRECTORY_LOCATION / imagePlugin.Info.SectorSize;
sectorsToRead = OLD_DIRECTORY_SIZE / imagePlugin.Info.SectorSize;
if(OLD_DIRECTORY_SIZE % imagePlugin.Info.SectorSize > 0) sectorsToRead++;
sector = imagePlugin.ReadSectors(sbSector, sectorsToRead);
if(sector.Length > OLD_DIRECTORY_SIZE)
{
byte[] tmp = new byte[OLD_DIRECTORY_SIZE];
Array.Copy(sector, 0, tmp, 0, OLD_DIRECTORY_SIZE - 53);
Array.Copy(sector, sector.Length - 54, tmp, OLD_DIRECTORY_SIZE - 54, 53);
Array.Copy(sector, sector.Length - 54, tmp, OLD_DIRECTORY_SIZE - 54, 53);
sector = tmp;
}
ptr = GCHandle.Alloc(sector, GCHandleType.Pinned);
OldDirectory oldRoot =
(OldDirectory)Marshal.PtrToStructure(ptr.AddrOfPinnedObject(), typeof(OldDirectory));
@@ -330,18 +333,20 @@ namespace DiscImageChef.Filesystems
else
{
// RISC OS says the old directory can't be in the new location, hard disks created by RISC OS 3.10 do that...
sbSector = NEW_DIRECTORY_LOCATION / imagePlugin.Info.SectorSize;
sectorsToRead = NEW_DIRECTORY_SIZE / imagePlugin.Info.SectorSize;
if(NEW_DIRECTORY_SIZE % imagePlugin.Info.SectorSize > 0) sectorsToRead++;
sbSector = NEW_DIRECTORY_LOCATION / imagePlugin.Info.SectorSize;
sectorsToRead = NEW_DIRECTORY_SIZE / imagePlugin.Info.SectorSize;
if(NEW_DIRECTORY_SIZE % imagePlugin.Info.SectorSize > 0) sectorsToRead++;
sector = imagePlugin.ReadSectors(sbSector, sectorsToRead);
if(sector.Length > OLD_DIRECTORY_SIZE)
{
byte[] tmp = new byte[OLD_DIRECTORY_SIZE];
Array.Copy(sector, 0, tmp, 0, OLD_DIRECTORY_SIZE - 53);
Array.Copy(sector, sector.Length - 54, tmp, OLD_DIRECTORY_SIZE - 54, 53);
Array.Copy(sector, sector.Length - 54, tmp, OLD_DIRECTORY_SIZE - 54,
53);
sector = tmp;
}
ptr = GCHandle.Alloc(sector, GCHandleType.Pinned);
oldRoot = (OldDirectory)Marshal.PtrToStructure(ptr.AddrOfPinnedObject(),
typeof(OldDirectory));
@@ -355,9 +360,11 @@ namespace DiscImageChef.Filesystems
{
byte[] tmp = new byte[NEW_DIRECTORY_SIZE];
Array.Copy(sector, 0, tmp, 0, NEW_DIRECTORY_SIZE - 41);
Array.Copy(sector, sector.Length - 42, tmp, NEW_DIRECTORY_SIZE - 42, 41);
Array.Copy(sector, sector.Length - 42, tmp, NEW_DIRECTORY_SIZE - 42,
41);
sector = tmp;
}
ptr = GCHandle.Alloc(sector, GCHandleType.Pinned);
NewDirectory newRoot =
(NewDirectory)Marshal.PtrToStructure(ptr.AddrOfPinnedObject(),
@@ -379,6 +386,7 @@ namespace DiscImageChef.Filesystems
XmlFsType.VolumeSerial = $"{oldMap1.discId:X4}";
sbInformation.AppendFormat("Volume ID: {0:X4}", oldMap1.discId).AppendLine();
}
if(!ArrayHelpers.ArrayIsNullOrEmpty(namebytes))
XmlFsType.VolumeName = StringHandlers.CToString(namebytes, Encoding);
@@ -393,18 +401,18 @@ namespace DiscImageChef.Filesystems
sector = imagePlugin.ReadSector(partition.Start);
byte newChk = NewMapChecksum(sector);
DicConsole.DebugWriteLine("ADFS Plugin", "newChk = {0}", newChk);
DicConsole.DebugWriteLine("ADFS Plugin", "newChk = {0}", newChk);
DicConsole.DebugWriteLine("ADFS Plugin", "map.zoneChecksum = {0}", sector[0]);
sbSector = BOOT_BLOCK_LOCATION / imagePlugin.Info.SectorSize;
sectorsToRead = BOOT_BLOCK_SIZE / imagePlugin.Info.SectorSize;
if(BOOT_BLOCK_SIZE % imagePlugin.Info.SectorSize > 0) sectorsToRead++;
sbSector = BOOT_BLOCK_LOCATION / imagePlugin.Info.SectorSize;
sectorsToRead = BOOT_BLOCK_SIZE / imagePlugin.Info.SectorSize;
if(BOOT_BLOCK_SIZE % imagePlugin.Info.SectorSize > 0) sectorsToRead++;
byte[] bootSector = imagePlugin.ReadSectors(sbSector + partition.Start, sectorsToRead);
int bootChk = 0;
byte[] bootSector = imagePlugin.ReadSectors(sbSector + partition.Start, sectorsToRead);
int bootChk = 0;
for(int i = 0; i < 0x1FF; i++) bootChk = (bootChk & 0xFF) + (bootChk >> 8) + bootSector[i];
DicConsole.DebugWriteLine("ADFS Plugin", "bootChk = {0}", bootChk);
DicConsole.DebugWriteLine("ADFS Plugin", "bootChk = {0}", bootChk);
DicConsole.DebugWriteLine("ADFS Plugin", "bBlock.checksum = {0}", bootSector[0x1FF]);
if(newChk == sector[0] && newChk != 0)
@@ -424,27 +432,27 @@ namespace DiscImageChef.Filesystems
else return;
DicConsole.DebugWriteLine("ADFS Plugin", "drSb.log2secsize = {0}", drSb.log2secsize);
DicConsole.DebugWriteLine("ADFS Plugin", "drSb.spt = {0}", drSb.spt);
DicConsole.DebugWriteLine("ADFS Plugin", "drSb.heads = {0}", drSb.heads);
DicConsole.DebugWriteLine("ADFS Plugin", "drSb.density = {0}", drSb.density);
DicConsole.DebugWriteLine("ADFS Plugin", "drSb.idlen = {0}", drSb.idlen);
DicConsole.DebugWriteLine("ADFS Plugin", "drSb.log2bpmb = {0}", drSb.log2bpmb);
DicConsole.DebugWriteLine("ADFS Plugin", "drSb.skew = {0}", drSb.skew);
DicConsole.DebugWriteLine("ADFS Plugin", "drSb.bootoption = {0}", drSb.bootoption);
DicConsole.DebugWriteLine("ADFS Plugin", "drSb.lowsector = {0}", drSb.lowsector);
DicConsole.DebugWriteLine("ADFS Plugin", "drSb.nzones = {0}", drSb.nzones);
DicConsole.DebugWriteLine("ADFS Plugin", "drSb.zone_spare = {0}", drSb.zone_spare);
DicConsole.DebugWriteLine("ADFS Plugin", "drSb.root = {0}", drSb.root);
DicConsole.DebugWriteLine("ADFS Plugin", "drSb.disc_size = {0}", drSb.disc_size);
DicConsole.DebugWriteLine("ADFS Plugin", "drSb.disc_id = {0}", drSb.disc_id);
DicConsole.DebugWriteLine("ADFS Plugin", "drSb.spt = {0}", drSb.spt);
DicConsole.DebugWriteLine("ADFS Plugin", "drSb.heads = {0}", drSb.heads);
DicConsole.DebugWriteLine("ADFS Plugin", "drSb.density = {0}", drSb.density);
DicConsole.DebugWriteLine("ADFS Plugin", "drSb.idlen = {0}", drSb.idlen);
DicConsole.DebugWriteLine("ADFS Plugin", "drSb.log2bpmb = {0}", drSb.log2bpmb);
DicConsole.DebugWriteLine("ADFS Plugin", "drSb.skew = {0}", drSb.skew);
DicConsole.DebugWriteLine("ADFS Plugin", "drSb.bootoption = {0}", drSb.bootoption);
DicConsole.DebugWriteLine("ADFS Plugin", "drSb.lowsector = {0}", drSb.lowsector);
DicConsole.DebugWriteLine("ADFS Plugin", "drSb.nzones = {0}", drSb.nzones);
DicConsole.DebugWriteLine("ADFS Plugin", "drSb.zone_spare = {0}", drSb.zone_spare);
DicConsole.DebugWriteLine("ADFS Plugin", "drSb.root = {0}", drSb.root);
DicConsole.DebugWriteLine("ADFS Plugin", "drSb.disc_size = {0}", drSb.disc_size);
DicConsole.DebugWriteLine("ADFS Plugin", "drSb.disc_id = {0}", drSb.disc_id);
DicConsole.DebugWriteLine("ADFS Plugin", "drSb.disc_name = {0}",
StringHandlers.CToString(drSb.disc_name, Encoding));
DicConsole.DebugWriteLine("ADFS Plugin", "drSb.disc_type = {0}", drSb.disc_type);
DicConsole.DebugWriteLine("ADFS Plugin", "drSb.disc_type = {0}", drSb.disc_type);
DicConsole.DebugWriteLine("ADFS Plugin", "drSb.disc_size_high = {0}", drSb.disc_size_high);
DicConsole.DebugWriteLine("ADFS Plugin", "drSb.flags = {0}", drSb.flags);
DicConsole.DebugWriteLine("ADFS Plugin", "drSb.nzones_high = {0}", drSb.nzones_high);
DicConsole.DebugWriteLine("ADFS Plugin", "drSb.flags = {0}", drSb.flags);
DicConsole.DebugWriteLine("ADFS Plugin", "drSb.nzones_high = {0}", drSb.nzones_high);
DicConsole.DebugWriteLine("ADFS Plugin", "drSb.format_version = {0}", drSb.format_version);
DicConsole.DebugWriteLine("ADFS Plugin", "drSb.root_size = {0}", drSb.root_size);
DicConsole.DebugWriteLine("ADFS Plugin", "drSb.root_size = {0}", drSb.root_size);
if(drSb.log2secsize < 8 || drSb.log2secsize > 10) return;
@@ -454,7 +462,7 @@ namespace DiscImageChef.Filesystems
if(!ArrayHelpers.ArrayIsNullOrEmpty(drSb.reserved)) return;
bytes = drSb.disc_size_high;
bytes = drSb.disc_size_high;
bytes *= 0x100000000;
bytes += drSb.disc_size;
@@ -485,6 +493,7 @@ namespace DiscImageChef.Filesystems
XmlFsType.VolumeSerial = $"{drSb.disc_id:X4}";
sbInformation.AppendFormat("Volume ID: {0:X4}", drSb.disc_id).AppendLine();
}
if(!ArrayHelpers.ArrayIsNullOrEmpty(drSb.disc_name))
{
string discname = StringHandlers.CToString(drSb.disc_name, Encoding);
@@ -494,15 +503,15 @@ namespace DiscImageChef.Filesystems
information = sbInformation.ToString();
XmlFsType.Bootable |= drSb.bootoption != 0; // Or not?
XmlFsType.Clusters = (long)(bytes / (ulong)(1 << drSb.log2secsize));
XmlFsType.ClusterSize = 1 << drSb.log2secsize;
XmlFsType.Type = "Acorn Advanced Disc Filing System";
XmlFsType.Bootable |= drSb.bootoption != 0; // Or not?
XmlFsType.Clusters = (long)(bytes / (ulong)(1 << drSb.log2secsize));
XmlFsType.ClusterSize = 1 << drSb.log2secsize;
XmlFsType.Type = "Acorn Advanced Disc Filing System";
}
byte AcornMapChecksum(byte[] data, int length)
{
int sum = 0;
int sum = 0;
int carry = 0;
if(length > data.Length) length = data.Length;
@@ -515,8 +524,8 @@ namespace DiscImageChef.Filesystems
sum += data[i] + carry;
if(sum > 0xFF)
{
carry = 1;
sum &= 0xFF;
carry = 1;
sum &= 0xFF;
}
else carry = 0;
}
@@ -567,8 +576,8 @@ namespace DiscImageChef.Filesystems
{
uint carry = sum & 0x1FFF;
sum >>= 13;
sum ^= data[i];
sum += carry << 19;
sum ^= data[i];
sum += carry << 19;
}
return (byte)(((sum & 0xFF000000) >> 24) ^ ((sum & 0xFF0000) >> 16) ^ ((sum & 0xFF00) >> 8) ^ (sum & 0xFF));
@@ -580,11 +589,12 @@ namespace DiscImageChef.Filesystems
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct BootBlock
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x1C0)] public byte[] spare;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x1C0)]
public byte[] spare;
public DiscRecord discRecord;
public byte flags;
public ushort startCylinder;
public byte checksum;
public byte flags;
public ushort startCylinder;
public byte checksum;
}
/// <summary>
@@ -593,28 +603,30 @@ namespace DiscImageChef.Filesystems
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct DiscRecord
{
public byte log2secsize;
public byte spt;
public byte heads;
public byte density;
public byte idlen;
public byte log2bpmb;
public byte skew;
public byte bootoption;
public byte lowsector;
public byte nzones;
public byte log2secsize;
public byte spt;
public byte heads;
public byte density;
public byte idlen;
public byte log2bpmb;
public byte skew;
public byte bootoption;
public byte lowsector;
public byte nzones;
public ushort zone_spare;
public uint root;
public uint disc_size;
public uint root;
public uint disc_size;
public ushort disc_id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)] public byte[] disc_name;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
public byte[] disc_name;
public uint disc_type;
public uint disc_size_high;
public byte flags;
public byte nzones_high;
public uint format_version;
public uint root_size;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] public byte[] reserved;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public byte[] reserved;
}
/// <summary>
@@ -623,10 +635,13 @@ namespace DiscImageChef.Filesystems
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct OldMapSector0
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 82 * 3)] public byte[] freeStart;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 82 * 3)]
public byte[] freeStart;
public byte reserved;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)] public byte[] name;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] public byte[] size;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
public byte[] name;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public byte[] size;
public byte checksum;
}
@@ -636,12 +651,14 @@ namespace DiscImageChef.Filesystems
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct OldMapSector1
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 82 * 3)] public byte[] freeStart;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)] public byte[] name;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 82 * 3)]
public byte[] freeStart;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
public byte[] name;
public ushort discId;
public byte boot;
public byte freeEnd;
public byte checksum;
public byte boot;
public byte freeEnd;
public byte checksum;
}
/// <summary>
@@ -650,9 +667,9 @@ namespace DiscImageChef.Filesystems
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct NewMap
{
public byte zoneChecksum;
public ushort freeLink;
public byte crossChecksum;
public byte zoneChecksum;
public ushort freeLink;
public byte crossChecksum;
public DiscRecord discRecord;
}
@@ -672,11 +689,13 @@ namespace DiscImageChef.Filesystems
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct DirectoryEntry
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)] public byte[] name;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
public byte[] name;
public uint load;
public uint exec;
public uint length;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] public byte[] address;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public byte[] address;
public byte atts;
}
@@ -686,11 +705,14 @@ namespace DiscImageChef.Filesystems
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct NewDirectoryTail
{
public byte lastMark;
public byte lastMark;
public ushort reserved;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] public byte[] parent;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 19)] public byte[] title;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)] public byte[] name;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public byte[] parent;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 19)]
public byte[] title;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
public byte[] name;
public byte endMasSeq;
public uint magic;
public byte checkByte;
@@ -703,10 +725,14 @@ namespace DiscImageChef.Filesystems
struct OldDirectoryTail
{
public byte lastMark;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)] public byte[] name;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] public byte[] parent;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 19)] public byte[] title;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 14)] public byte[] reserved;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
public byte[] name;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public byte[] parent;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 19)]
public byte[] title;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 14)]
public byte[] reserved;
public byte endMasSeq;
public uint magic;
public byte checkByte;
@@ -719,7 +745,8 @@ namespace DiscImageChef.Filesystems
struct OldDirectory
{
public DirectoryHeader header;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 47)] public DirectoryEntry[] entries;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 47)]
public DirectoryEntry[] entries;
public OldDirectoryTail tail;
}
@@ -730,7 +757,8 @@ namespace DiscImageChef.Filesystems
struct NewDirectory
{
public DirectoryHeader header;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 77)] public DirectoryEntry[] entries;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 77)]
public DirectoryEntry[] entries;
public NewDirectoryTail tail;
}
}

View File

@@ -83,7 +83,7 @@ namespace DiscImageChef.Filesystems
// Clear checksum on sector
sector[4] = sector[5] = sector[6] = sector[7] = 0;
uint bsum = AmigaBootChecksum(sector);
uint bsum = AmigaBootChecksum(sector);
DicConsole.DebugWriteLine("AmigaDOS plugin", "bblk.checksum = 0x{0:X8}", bblk.checksum);
DicConsole.DebugWriteLine("AmigaDOS plugin", "bsum = 0x{0:X8}", bsum);
@@ -99,10 +99,11 @@ namespace DiscImageChef.Filesystems
ulong[] rootPtrs =
{
bRootPtr + partition.Start, (partition.End - partition.Start + 1) / 2 + partition.Start - 2,
(partition.End - partition.Start + 1) / 2 + partition.Start - 1,
(partition.End - partition.Start + 1) / 2 + partition.Start,
(partition.End - partition.Start + 1) / 2 + partition.Start + 4
bRootPtr + partition.Start, (partition.End - partition.Start + 1) / 2 + partition.Start - 2,
(partition.End - partition.Start + 1) / 2 + partition.Start - 1,
(partition.End - partition.Start + 1) / 2 +
partition.Start,
(partition.End - partition.Start + 1) / 2 + partition.Start + 4
};
RootBlock rblk = new RootBlock();
@@ -123,7 +124,7 @@ namespace DiscImageChef.Filesystems
DicConsole.DebugWriteLine("AmigaDOS plugin", "rblk.hashTableSize = {0}", rblk.hashTableSize);
uint blockSize = (rblk.hashTableSize + 56) * 4;
uint sectorsPerBlock = (uint)(blockSize / sector.Length);
uint sectorsPerBlock = (uint)(blockSize / sector.Length);
DicConsole.DebugWriteLine("AmigaDOS plugin", "blockSize = {0}", blockSize);
DicConsole.DebugWriteLine("AmigaDOS plugin", "sectorsPerBlock = {0}", sectorsPerBlock);
@@ -137,7 +138,7 @@ namespace DiscImageChef.Filesystems
// Clear checksum on sector
rblk.checksum = BigEndianBitConverter.ToUInt32(sector, 20);
sector[20] = sector[21] = sector[22] = sector[23] = 0;
uint rsum = AmigaChecksum(sector);
uint rsum = AmigaChecksum(sector);
DicConsole.DebugWriteLine("AmigaDOS plugin", "rblk.checksum = 0x{0:X8}", rblk.checksum);
DicConsole.DebugWriteLine("AmigaDOS plugin", "rsum = 0x{0:X8}", rsum);
@@ -154,8 +155,8 @@ namespace DiscImageChef.Filesystems
public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
Encoding encoding)
{
Encoding = encoding ?? Encoding.GetEncoding("iso-8859-1");
StringBuilder sbInformation = new StringBuilder();
Encoding = encoding ?? Encoding.GetEncoding("iso-8859-1");
StringBuilder sbInformation = new StringBuilder();
XmlFsType = new FileSystemType();
information = null;
BigEndianBitConverter.IsLittleEndian = BitConverter.IsLittleEndian;
@@ -163,10 +164,10 @@ namespace DiscImageChef.Filesystems
byte[] bootBlockSectors = imagePlugin.ReadSectors(0 + partition.Start, 2);
BootBlock bootBlk = BigEndianMarshal.ByteArrayToStructureBigEndian<BootBlock>(bootBlockSectors);
bootBlk.bootCode = new byte[bootBlockSectors.Length - 12];
bootBlk.bootCode = new byte[bootBlockSectors.Length - 12];
Array.Copy(bootBlockSectors, 12, bootBlk.bootCode, 0, bootBlk.bootCode.Length);
bootBlockSectors[4] = bootBlockSectors[5] = bootBlockSectors[6] = bootBlockSectors[7] = 0;
uint bsum = AmigaBootChecksum(bootBlockSectors);
uint bsum = AmigaBootChecksum(bootBlockSectors);
ulong bRootPtr = 0;
@@ -179,10 +180,11 @@ namespace DiscImageChef.Filesystems
ulong[] rootPtrs =
{
bRootPtr + partition.Start, (partition.End - partition.Start + 1) / 2 + partition.Start - 2,
(partition.End - partition.Start + 1) / 2 + partition.Start - 1,
(partition.End - partition.Start + 1) / 2 + partition.Start,
(partition.End - partition.Start + 1) / 2 + partition.Start + 4
bRootPtr + partition.Start, (partition.End - partition.Start + 1) / 2 + partition.Start - 2,
(partition.End - partition.Start + 1) / 2 + partition.Start - 1,
(partition.End - partition.Start + 1) / 2 +
partition.Start,
(partition.End - partition.Start + 1) / 2 + partition.Start + 4
};
RootBlock rootBlk = new RootBlock();
@@ -206,8 +208,8 @@ namespace DiscImageChef.Filesystems
DicConsole.DebugWriteLine("AmigaDOS plugin", "rootBlk.hashTableSize = {0}", rootBlk.hashTableSize);
blockSize = (rootBlk.hashTableSize + 56) * 4;
uint sectorsPerBlock = (uint)(blockSize / rootBlockSector.Length);
blockSize = (rootBlk.hashTableSize + 56) * 4;
uint sectorsPerBlock = (uint)(blockSize / rootBlockSector.Length);
DicConsole.DebugWriteLine("AmigaDOS plugin", "blockSize = {0}", blockSize);
DicConsole.DebugWriteLine("AmigaDOS plugin", "sectorsPerBlock = {0}", sectorsPerBlock);
@@ -221,7 +223,7 @@ namespace DiscImageChef.Filesystems
// Clear checksum on sector
rootBlk.checksum = BigEndianBitConverter.ToUInt32(rootBlockSector, 20);
rootBlockSector[20] = rootBlockSector[21] = rootBlockSector[22] = rootBlockSector[23] = 0;
uint rsum = AmigaChecksum(rootBlockSector);
uint rsum = AmigaChecksum(rootBlockSector);
DicConsole.DebugWriteLine("AmigaDOS plugin", "rootBlk.checksum = 0x{0:X8}", rootBlk.checksum);
DicConsole.DebugWriteLine("AmigaDOS plugin", "rsum = 0x{0:X8}", rsum);
@@ -303,7 +305,7 @@ namespace DiscImageChef.Filesystems
long blocks = (long)((partition.End - partition.Start + 1) * imagePlugin.Info.SectorSize / blockSize);
sbInformation.AppendFormat("Volume block size is {0} bytes", blockSize).AppendLine();
sbInformation.AppendFormat("Volume has {0} blocks", blocks).AppendLine();
sbInformation.AppendFormat("Volume has {0} blocks", blocks).AppendLine();
sbInformation.AppendFormat("Volume created on {0}",
DateHandlers.AmigaToDateTime(rootBlk.cDays, rootBlk.cMins, rootBlk.cTicks))
.AppendLine();
@@ -319,7 +321,7 @@ namespace DiscImageChef.Filesystems
XmlFsType.CreationDate =
DateHandlers.AmigaToDateTime(rootBlk.cDays, rootBlk.cMins, rootBlk.cTicks);
XmlFsType.CreationDateSpecified = true;
XmlFsType.ModificationDate =
XmlFsType.ModificationDate =
DateHandlers.AmigaToDateTime(rootBlk.vDays, rootBlk.vMins, rootBlk.vTicks);
XmlFsType.ModificationDateSpecified = true;
XmlFsType.Dirty = rootBlk.bitmapFlag != 0xFFFFFFFF;
@@ -336,7 +338,7 @@ namespace DiscImageChef.Filesystems
byte[] tmp = new byte[228];
Array.Copy(block, 0, tmp, 0, 24);
Array.Copy(block, block.Length - 200, tmp, 28, 200);
RootBlock root = BigEndianMarshal.ByteArrayToStructureBigEndian<RootBlock>(tmp);
RootBlock root = BigEndianMarshal.ByteArrayToStructureBigEndian<RootBlock>(tmp);
root.hashTable = new uint[(block.Length - 224) / 4];
BigEndianBitConverter.IsLittleEndian = BitConverter.IsLittleEndian;
for(int i = 0; i < root.hashTable.Length; i++)

View File

@@ -58,7 +58,7 @@ namespace DiscImageChef.Filesystems.AppleDOS
public Guid Id => new Guid("8658A1E9-B2E7-4BCC-9638-157A31B0A700\n");
public IEnumerable<(string name, Type type, string description)> SupportedOptions =>
new(string name, Type type, string description)[] { };
new (string name, Type type, string description)[] { };
static Dictionary<string, string> GetDefaultOptions()
{

View File

@@ -80,12 +80,12 @@ namespace DiscImageChef.Filesystems.AppleDOS
Errno ReadCatalog()
{
MemoryStream catalogMs = new MemoryStream();
ulong lba = (ulong)(vtoc.catalogTrack * sectorsPerTrack + vtoc.catalogSector);
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>();
catalogCache = new Dictionary<string, ushort>();
fileTypeCache = new Dictionary<string, byte>();
fileSizeCache = new Dictionary<string, int>();
lockedFiles = new List<string>();
if(lba == 0 || lba > device.Info.Sectors) return Errno.InvalidArgument;
@@ -108,7 +108,7 @@ namespace DiscImageChef.Filesystems.AppleDOS
track2UsedByFiles |= entry.extentTrack == 2;
byte[] filenameB = new byte[30];
ushort ts = (ushort)((entry.extentTrack << 8) | entry.extentSector);
ushort ts = (ushort)((entry.extentTrack << 8) | entry.extentSector);
// Apple DOS has high byte set over ASCII.
for(int i = 0; i < 30; i++) filenameB[i] = (byte)(entry.filename[i] & 0x7F);

View File

@@ -52,11 +52,11 @@ namespace DiscImageChef.Filesystems.AppleDOS
if(!fileCache.ContainsKey(filename)) return Errno.NoSuchFile;
attributes = FileAttributes.Extents;
attributes = FileAttributes.Extents;
attributes |= FileAttributes.File;
if(lockedFiles.Contains(filename)) attributes |= FileAttributes.ReadOnly;
if(debug && (string.Compare(path, "$", StringComparison.InvariantCulture) == 0 ||
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;
@@ -75,12 +75,13 @@ namespace DiscImageChef.Filesystems.AppleDOS
string filename = pathElements[0].ToUpperInvariant();
if(filename.Length > 30) return Errno.NameTooLong;
if(debug && (string.Compare(path, "$", StringComparison.InvariantCulture) == 0 ||
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, "$", StringComparison.InvariantCulture) == 0)
file = catalogBlocks;
else if(string.Compare(path, "$Vtoc", StringComparison.InvariantCulture) == 0) file = vtocBlocks;
else file = bootBlocks;
else file = bootBlocks;
else
{
if(!fileCache.TryGetValue(filename, out file))
@@ -121,7 +122,7 @@ namespace DiscImageChef.Filesystems.AppleDOS
fileSizeCache.TryGetValue(filename, out int filesize);
GetAttributes(path, out FileAttributes attrs);
if(debug && (string.Compare(path, "$", StringComparison.InvariantCulture) == 0 ||
if(debug && (string.Compare(path, "$", StringComparison.InvariantCulture) == 0 ||
string.Compare(path, "$Boot", StringComparison.InvariantCulture) == 0 ||
string.Compare(path, "$Vtoc", StringComparison.InvariantCulture) == 0))
{
@@ -141,8 +142,8 @@ namespace DiscImageChef.Filesystems.AppleDOS
}
stat.Attributes = attrs;
stat.BlockSize = vtoc.bytesPerSector;
stat.Links = 1;
stat.BlockSize = vtoc.bytesPerSector;
stat.Links = 1;
return Errno.NoError;
}
@@ -164,10 +165,10 @@ namespace DiscImageChef.Filesystems.AppleDOS
if(!catalogCache.TryGetValue(filename, out ushort ts)) return Errno.NoSuchFile;
ulong lba = (ulong)(((ts & 0xFF00) >> 8) * sectorsPerTrack + (ts & 0xFF));
MemoryStream fileMs = new MemoryStream();
MemoryStream tsListMs = new MemoryStream();
ushort expectedBlock = 0;
ulong lba = (ulong)(((ts & 0xFF00) >> 8) * sectorsPerTrack + (ts & 0xFF));
MemoryStream fileMs = new MemoryStream();
MemoryStream tsListMs = new MemoryStream();
ushort expectedBlock = 0;
while(lba != 0)
{
@@ -216,7 +217,7 @@ namespace DiscImageChef.Filesystems.AppleDOS
Errno CacheAllFiles()
{
fileCache = new Dictionary<string, byte[]>();
fileCache = new Dictionary<string, byte[]>();
extentCache = new Dictionary<string, byte[]>();
foreach(Errno error in catalogCache.Keys.Select(CacheFile).Where(error => error != Errno.NoError))
@@ -226,7 +227,7 @@ namespace DiscImageChef.Filesystems.AppleDOS
if(!track1UsedByFiles) tracksOnBoot++;
if(!track2UsedByFiles) tracksOnBoot++;
bootBlocks = device.ReadSectors(0, (uint)(tracksOnBoot * sectorsPerTrack));
bootBlocks = device.ReadSectors(0, (uint)(tracksOnBoot * sectorsPerTrack));
usedSectors += bootBlocks.Length / vtoc.bytesPerSector;
return Errno.NoError;

View File

@@ -58,14 +58,14 @@ namespace DiscImageChef.Filesystems.AppleDOS
vtoc = (Vtoc)Marshal.PtrToStructure(vtocPtr, typeof(Vtoc));
Marshal.FreeHGlobal(vtocPtr);
return vtoc.catalogSector < spt && vtoc.maxTrackSectorPairsPerSector <= 122 &&
vtoc.sectorsPerTrack == spt && vtoc.bytesPerSector == 256;
return vtoc.catalogSector < spt && vtoc.maxTrackSectorPairsPerSector <= 122 &&
vtoc.sectorsPerTrack == spt && vtoc.bytesPerSector == 256;
}
public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
Encoding encoding)
Encoding encoding)
{
Encoding = encoding ?? new Apple2();
Encoding = encoding ?? new Apple2();
information = "";
StringBuilder sb = new StringBuilder();
@@ -96,10 +96,10 @@ namespace DiscImageChef.Filesystems.AppleDOS
XmlFsType = new FileSystemType
{
Bootable = true,
Clusters = (long)imagePlugin.Info.Sectors,
Bootable = true,
Clusters = (long)imagePlugin.Info.Sectors,
ClusterSize = (int)imagePlugin.Info.SectorSize,
Type = "Apple DOS"
Type = "Apple DOS"
};
}
}

View File

@@ -43,18 +43,23 @@ namespace DiscImageChef.Filesystems.AppleDOS
public byte catalogTrack;
public byte catalogSector;
public byte dosRelease;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] public byte[] unused2;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public byte[] unused2;
public byte volumeNumber;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] public byte[] unused3;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public byte[] unused3;
public byte maxTrackSectorPairsPerSector;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] public byte[] unused4;
public byte lastAllocatedSector;
[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;
[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;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 200)]
public byte[] bitmap;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
@@ -63,8 +68,10 @@ namespace DiscImageChef.Filesystems.AppleDOS
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;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public byte[] unused2;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 7)]
public FileEntry[] entries;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
@@ -73,7 +80,8 @@ namespace DiscImageChef.Filesystems.AppleDOS
public byte extentTrack;
public byte extentSector;
public byte typeAndFlags;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 30)] public byte[] filename;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 30)]
public byte[] filename;
public ushort length;
}
@@ -83,10 +91,13 @@ namespace DiscImageChef.Filesystems.AppleDOS
public byte unused1;
public byte nextListTrack;
public byte nextListSector;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] public byte[] unused2;
[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;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
public byte[] unused3;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 122)]
public TrackSectorListEntry[] entries;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]

View File

@@ -75,8 +75,8 @@ namespace DiscImageChef.Filesystems.AppleDOS
sectorsPerTrack = device.Info.Sectors == 455 ? 13 : 16;
// Read the VTOC
vtocBlocks = device.ReadSector((ulong)(17 * sectorsPerTrack));
vtoc = new Vtoc();
vtocBlocks = device.ReadSector((ulong)(17 * sectorsPerTrack));
vtoc = new Vtoc();
IntPtr vtocPtr = Marshal.AllocHGlobal(256);
Marshal.Copy(vtocBlocks, 0, vtocPtr, 256);
vtoc = (Vtoc)Marshal.PtrToStructure(vtocPtr, typeof(Vtoc));

View File

@@ -56,7 +56,7 @@ namespace DiscImageChef.Filesystems.AppleDOS
xattrs = new List<string>();
if(debug && (string.Compare(path, "$", StringComparison.InvariantCulture) == 0 ||
if(debug && (string.Compare(path, "$", StringComparison.InvariantCulture) == 0 ||
string.Compare(path, "$Boot", StringComparison.InvariantCulture) == 0 ||
string.Compare(path, "$Vtoc", StringComparison.InvariantCulture) == 0)) { }
else
@@ -88,7 +88,7 @@ namespace DiscImageChef.Filesystems.AppleDOS
string filename = pathElements[0].ToUpperInvariant();
if(filename.Length > 30) return Errno.NameTooLong;
if(debug && (string.Compare(path, "$", StringComparison.InvariantCulture) == 0 ||
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;
@@ -99,7 +99,7 @@ namespace DiscImageChef.Filesystems.AppleDOS
{
if(!fileTypeCache.TryGetValue(filename, out byte type)) return Errno.InvalidArgument;
buf = new byte[1];
buf = new byte[1];
buf[0] = type;
return Errno.NoError;
}

View File

@@ -57,9 +57,9 @@ namespace DiscImageChef.Filesystems
const ushort HFSBB_MAGIC = 0x4C4B;
public FileSystemType XmlFsType { get; private set; }
public Encoding Encoding { get; private set; }
public string Name => "Apple Hierarchical File System";
public Guid Id => new Guid("36405F8D-0D26-6ECC-0BBB-1D5225FF404F");
public Encoding Encoding { get; private set; }
public string Name => "Apple Hierarchical File System";
public Guid Id => new Guid("36405F8D-0D26-6ECC-0BBB-1D5225FF404F");
public bool Identify(IMediaImage imagePlugin, Partition partition)
{
@@ -100,14 +100,14 @@ namespace DiscImageChef.Filesystems
}
public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
Encoding encoding)
Encoding encoding)
{
Encoding = encoding ?? Encoding.GetEncoding("macintosh");
Encoding = encoding ?? Encoding.GetEncoding("macintosh");
information = "";
StringBuilder sb = new StringBuilder();
byte[] bbSector = null;
byte[] bbSector = null;
byte[] mdbSector = null;
ushort drSigWord;
@@ -123,7 +123,7 @@ namespace DiscImageChef.Filesystems
drSigWord = BigEndianBitConverter.ToUInt16(tmpSector, offset);
if(drSigWord != HFS_MAGIC) continue;
bbSector = new byte[1024];
bbSector = new byte[1024];
mdbSector = new byte[512];
if(offset >= 0x400) Array.Copy(tmpSector, offset - 0x400, bbSector, 0, 1024);
Array.Copy(tmpSector, offset, mdbSector, 0, 512);
@@ -162,9 +162,9 @@ namespace DiscImageChef.Filesystems
if((mdb.drAtrb & 0x80) == 0x80) sb.AppendLine("Volume is locked by hardware.");
sb.AppendLine((mdb.drAtrb & 0x100) == 0x100 ? "Volume was unmonted." : "Volume is mounted.");
if((mdb.drAtrb & 0x200) == 0x200) sb.AppendLine("Volume has spared bad blocks.");
if((mdb.drAtrb & 0x400) == 0x400) sb.AppendLine("Volume does not need cache.");
if((mdb.drAtrb & 0x800) == 0x800) sb.AppendLine("Boot volume is inconsistent.");
if((mdb.drAtrb & 0x200) == 0x200) sb.AppendLine("Volume has spared bad blocks.");
if((mdb.drAtrb & 0x400) == 0x400) sb.AppendLine("Volume does not need cache.");
if((mdb.drAtrb & 0x800) == 0x800) sb.AppendLine("Boot volume is inconsistent.");
if((mdb.drAtrb & 0x1000) == 0x1000) sb.AppendLine("There are reused CNIDs.");
if((mdb.drAtrb & 0x2000) == 0x2000) sb.AppendLine("Volume is journaled.");
if((mdb.drAtrb & 0x4000) == 0x4000) sb.AppendLine("Volume is seriously inconsistent.");
@@ -223,7 +223,7 @@ namespace DiscImageChef.Filesystems
if((bb.boot_flags & 0x80) == 0x80) sb.AppendLine("Boot block is in new unknown format.");
else
{
if(bb.boot_flags > 0) sb.AppendLine("Allocate secondary sound buffer at boot.");
if(bb.boot_flags > 0) sb.AppendLine("Allocate secondary sound buffer at boot.");
else if(bb.boot_flags < 0) sb.AppendLine("Allocate secondary sound and video buffers at boot.");
sb.AppendFormat("System filename: {0}", StringHandlers.PascalToString(bb.system_name, Encoding))
@@ -256,29 +256,32 @@ namespace DiscImageChef.Filesystems
XmlFsType = new FileSystemType();
if(mdb.drVolBkUp > 0)
{
XmlFsType.BackupDate = DateHandlers.MacToDateTime(mdb.drVolBkUp);
XmlFsType.BackupDate = DateHandlers.MacToDateTime(mdb.drVolBkUp);
XmlFsType.BackupDateSpecified = true;
}
XmlFsType.Bootable = bb.signature == HFSBB_MAGIC || mdb.drFndrInfo0 != 0 || mdb.drFndrInfo3 != 0 ||
XmlFsType.Bootable = bb.signature == HFSBB_MAGIC || mdb.drFndrInfo0 != 0 || mdb.drFndrInfo3 != 0 ||
mdb.drFndrInfo5 != 0;
XmlFsType.Clusters = mdb.drNmAlBlks;
XmlFsType.Clusters = mdb.drNmAlBlks;
XmlFsType.ClusterSize = (int)mdb.drAlBlkSiz;
if(mdb.drCrDate > 0)
{
XmlFsType.CreationDate = DateHandlers.MacToDateTime(mdb.drCrDate);
XmlFsType.CreationDate = DateHandlers.MacToDateTime(mdb.drCrDate);
XmlFsType.CreationDateSpecified = true;
}
XmlFsType.Dirty = (mdb.drAtrb & 0x100) != 0x100;
XmlFsType.Files = mdb.drFilCnt;
XmlFsType.FilesSpecified = true;
XmlFsType.FreeClusters = mdb.drFreeBks;
XmlFsType.Dirty = (mdb.drAtrb & 0x100) != 0x100;
XmlFsType.Files = mdb.drFilCnt;
XmlFsType.FilesSpecified = true;
XmlFsType.FreeClusters = mdb.drFreeBks;
XmlFsType.FreeClustersSpecified = true;
if(mdb.drLsMod > 0)
{
XmlFsType.ModificationDate = DateHandlers.MacToDateTime(mdb.drLsMod);
XmlFsType.ModificationDate = DateHandlers.MacToDateTime(mdb.drLsMod);
XmlFsType.ModificationDateSpecified = true;
}
XmlFsType.Type = "HFS";
XmlFsType.Type = "HFS";
XmlFsType.VolumeName = StringHandlers.PascalToString(mdb.drVN, Encoding);
if(mdb.drFndrInfo6 != 0 && mdb.drFndrInfo7 != 0)
XmlFsType.VolumeSerial = $"{mdb.drFndrInfo6:X8}{mdb.drFndrInfo7:X8}";
@@ -286,8 +289,8 @@ namespace DiscImageChef.Filesystems
static byte[] Read2048SectorAs512(IMediaImage imagePlugin, ulong lba)
{
ulong lba2K = lba / 4;
int remainder = (int)(lba % 4);
ulong lba2K = lba / 4;
int remainder = (int)(lba % 4);
byte[] buffer = imagePlugin.ReadSector(lba2K);
byte[] sector = new byte[512];
@@ -330,7 +333,8 @@ namespace DiscImageChef.Filesystems
/// <summary>0x022, Free allocation blocks</summary>
public ushort drFreeBks;
/// <summary>0x024, Volume name (28 bytes)</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 28)] public byte[] drVN;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 28)]
public byte[] drVN;
/// <summary>0x040, Volume last backup time</summary>
public uint drVolBkUp;
/// <summary>0x044, Volume backup sequence number</summary>
@@ -405,19 +409,26 @@ namespace DiscImageChef.Filesystems
/// <summary>0x006, Boot block flags</summary>
public short boot_flags;
/// <summary>0x00A, System file name (16 bytes)</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public byte[] system_name;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[] system_name;
/// <summary>0x01A, Finder file name (16 bytes)</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public byte[] finder_name;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[] finder_name;
/// <summary>0x02A, Debugger file name (16 bytes)</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public byte[] debug_name;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[] debug_name;
/// <summary>0x03A, Disassembler file name (16 bytes)</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public byte[] disasm_name;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[] disasm_name;
/// <summary>0x04A, Startup screen file name (16 bytes)</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public byte[] stupscr_name;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[] stupscr_name;
/// <summary>0x05A, First program to execute on boot (16 bytes)</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public byte[] bootup_name;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[] bootup_name;
/// <summary>0x06A, Clipboard file name (16 bytes)</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public byte[] clipbrd_name;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[] clipbrd_name;
/// <summary>0x07A, 1/4 of maximum opened at a time files</summary>
public ushort max_files;
/// <summary>0x07C, Event queue size</summary>

View File

@@ -56,9 +56,9 @@ namespace DiscImageChef.Filesystems
const ushort HFSX_MAGIC = 0x4858;
public FileSystemType XmlFsType { get; private set; }
public Encoding Encoding { get; private set; }
public string Name => "Apple HFS+ filesystem";
public Guid Id => new Guid("36405F8D-0D26-6EBE-436F-62F0586B4F08");
public Encoding Encoding { get; private set; }
public string Name => "Apple HFS+ filesystem";
public Guid Id => new Guid("36405F8D-0D26-6EBE-436F-62F0586B4F08");
public bool Identify(IMediaImage imagePlugin, Partition partition)
{
@@ -98,15 +98,15 @@ namespace DiscImageChef.Filesystems
}
public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
Encoding encoding)
Encoding encoding)
{
Encoding = Encoding.BigEndianUnicode;
Encoding = Encoding.BigEndianUnicode;
information = "";
HfsPlusVolumeHeader vh = new HfsPlusVolumeHeader();
ulong hfspOffset;
bool wrapped;
bool wrapped;
uint sectorsToRead = 0x800 / imagePlugin.Info.SectorSize;
if(0x800 % imagePlugin.Info.SectorSize > 0) sectorsToRead++;
@@ -128,24 +128,24 @@ namespace DiscImageChef.Filesystems
ushort drAlBlSt = BigEndianBitConverter.ToUInt16(vhSector, 0x41C);
hfspOffset = (ulong)((drAlBlSt * 512 + xdrStABNt * drAlBlkSiz) / imagePlugin.Info.SectorSize);
wrapped = true;
wrapped = true;
}
else
{
hfspOffset = 0;
wrapped = false;
wrapped = false;
}
}
else
{
hfspOffset = 0;
wrapped = false;
wrapped = false;
}
vhSector = imagePlugin.ReadSectors(partition.Start + hfspOffset, sectorsToRead); // Read volume header
vh.signature = BigEndianBitConverter.ToUInt16(vhSector, 0x400);
if(vh.signature != HFSP_MAGIC && vh.signature != HFSX_MAGIC) return;
StringBuilder sb = new StringBuilder();
@@ -178,15 +178,12 @@ namespace DiscImageChef.Filesystems
if((vh.attributes & 0x2000) == 0x2000)
sb.AppendFormat("Journal starts at allocation block {0}.", vh.journalInfoBlock).AppendLine();
sb.AppendFormat("Creation date: {0}", DateHandlers.MacToDateTime(vh.createDate)).AppendLine();
sb.AppendFormat("Last modification date: {0}", DateHandlers.MacToDateTime(vh.modifyDate))
.AppendLine();
sb.AppendFormat("Last modification date: {0}", DateHandlers.MacToDateTime(vh.modifyDate)).AppendLine();
if(vh.backupDate > 0)
sb.AppendFormat("Last backup date: {0}", DateHandlers.MacToDateTime(vh.backupDate))
.AppendLine();
sb.AppendFormat("Last backup date: {0}", DateHandlers.MacToDateTime(vh.backupDate)).AppendLine();
else sb.AppendLine("Volume has never been backed up");
if(vh.backupDate > 0)
sb.AppendFormat("Last check date: {0}", DateHandlers.MacToDateTime(vh.checkedDate))
.AppendLine();
sb.AppendFormat("Last check date: {0}", DateHandlers.MacToDateTime(vh.checkedDate)).AppendLine();
else sb.AppendLine("Volume has never been checked up");
sb.AppendFormat("{0} files on volume.", vh.fileCount).AppendLine();
sb.AppendFormat("{0} folders on volume.", vh.folderCount).AppendLine();
@@ -210,8 +207,7 @@ namespace DiscImageChef.Filesystems
sb.AppendFormat("CNID of bootable Mac OS 8 or 9 directory: {0}", vh.drFndrInfo3).AppendLine();
sb.AppendFormat("CNID of bootable Mac OS X directory: {0}", vh.drFndrInfo5).AppendLine();
if(vh.drFndrInfo6 != 0 && vh.drFndrInfo7 != 0)
sb.AppendFormat("Mac OS X Volume ID: {0:X8}{1:X8}", vh.drFndrInfo6, vh.drFndrInfo7)
.AppendLine();
sb.AppendFormat("Mac OS X Volume ID: {0:X8}{1:X8}", vh.drFndrInfo6, vh.drFndrInfo7).AppendLine();
XmlFsType = new FileSystemType();
if(vh.backupDate > 0)
@@ -219,6 +215,7 @@ namespace DiscImageChef.Filesystems
XmlFsType.BackupDate = DateHandlers.MacToDateTime(vh.backupDate);
XmlFsType.BackupDateSpecified = true;
}
XmlFsType.Bootable |= vh.drFndrInfo0 != 0 || vh.drFndrInfo3 != 0 || vh.drFndrInfo5 != 0;
XmlFsType.Clusters = vh.totalBlocks;
XmlFsType.ClusterSize = (int)vh.blockSize;
@@ -227,6 +224,7 @@ namespace DiscImageChef.Filesystems
XmlFsType.CreationDate = DateHandlers.MacToDateTime(vh.createDate);
XmlFsType.CreationDateSpecified = true;
}
XmlFsType.Dirty = (vh.attributes & 0x100) != 0x100;
XmlFsType.Files = vh.fileCount;
XmlFsType.FilesSpecified = true;
@@ -237,6 +235,7 @@ namespace DiscImageChef.Filesystems
XmlFsType.ModificationDate = DateHandlers.MacToDateTime(vh.modifyDate);
XmlFsType.ModificationDateSpecified = true;
}
if(vh.signature == 0x482B) XmlFsType.Type = "HFS+";
if(vh.signature == 0x4858) XmlFsType.Type = "HFSX";
if(vh.drFndrInfo6 != 0 && vh.drFndrInfo7 != 0)
@@ -272,7 +271,8 @@ namespace DiscImageChef.Filesystems
/// "HFSJ" Journaled implementation
/// "fsck" /sbin/fsck
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] public byte[] lastMountedVersion;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public byte[] lastMountedVersion;
/// <summary>0x00C, Allocation block number containing the journal</summary>
public uint journalInfoBlock;
/// <summary>0x010, Date of volume creation</summary>

View File

@@ -69,7 +69,7 @@ namespace DiscImageChef.Filesystems.AppleMFS
// TODO: Implement Finder namespace (requires decoding Desktop database)
public IEnumerable<(string name, Type type, string description)> SupportedOptions =>
new(string name, Type type, string description)[] { };
new (string name, Type type, string description)[] { };
static Dictionary<string, string> GetDefaultOptions()
{

View File

@@ -39,13 +39,13 @@ namespace DiscImageChef.Filesystems.AppleMFS
// "LK"
const ushort MFSBB_MAGIC = 0x4C4B;
const short DIRID_TRASH = -3;
const short DIRID_DESKTOP = -2;
const short DIRID_TRASH = -3;
const short DIRID_DESKTOP = -2;
const short DIRID_TEMPLATE = -1;
const short DIRID_ROOT = 0;
const short DIRID_ROOT = 0;
const int BMAP_FREE = 0;
const int BMAP_LAST = 1;
const int BMAP_DIR = 0xFFF;
const int BMAP_DIR = 0xFFF;
}
}

View File

@@ -65,7 +65,7 @@ namespace DiscImageChef.Filesystems.AppleMFS
bool FillDirectory()
{
idToFilename = new Dictionary<uint, string>();
idToEntry = new Dictionary<uint, MFS_FileEntry>();
idToEntry = new Dictionary<uint, MFS_FileEntry>();
filenameToId = new Dictionary<string, uint>();
int offset = 0;
@@ -74,29 +74,29 @@ namespace DiscImageChef.Filesystems.AppleMFS
MFS_FileEntry entry = new MFS_FileEntry
{
flUsrWds = new byte[16],
flFlags = (MFS_FileFlags)directoryBlocks[offset + 0]
flFlags = (MFS_FileFlags)directoryBlocks[offset + 0]
};
if(!entry.flFlags.HasFlag(MFS_FileFlags.Used)) break;
entry.flTyp = directoryBlocks[offset + 1];
Array.Copy(directoryBlocks, offset + 2, entry.flUsrWds, 0, 16);
entry.flFlNum = BigEndianBitConverter.ToUInt32(directoryBlocks, offset + 18);
entry.flStBlk = BigEndianBitConverter.ToUInt16(directoryBlocks, offset + 22);
entry.flLgLen = BigEndianBitConverter.ToUInt32(directoryBlocks, offset + 24);
entry.flPyLen = BigEndianBitConverter.ToUInt32(directoryBlocks, offset + 28);
entry.flFlNum = BigEndianBitConverter.ToUInt32(directoryBlocks, offset + 18);
entry.flStBlk = BigEndianBitConverter.ToUInt16(directoryBlocks, offset + 22);
entry.flLgLen = BigEndianBitConverter.ToUInt32(directoryBlocks, offset + 24);
entry.flPyLen = BigEndianBitConverter.ToUInt32(directoryBlocks, offset + 28);
entry.flRStBlk = BigEndianBitConverter.ToUInt16(directoryBlocks, offset + 32);
entry.flRLgLen = BigEndianBitConverter.ToUInt32(directoryBlocks, offset + 34);
entry.flRPyLen = BigEndianBitConverter.ToUInt32(directoryBlocks, offset + 38);
entry.flCrDat = BigEndianBitConverter.ToUInt32(directoryBlocks, offset + 42);
entry.flMdDat = BigEndianBitConverter.ToUInt32(directoryBlocks, offset + 46);
entry.flNam = new byte[directoryBlocks[offset + 50] + 1];
entry.flCrDat = BigEndianBitConverter.ToUInt32(directoryBlocks, offset + 42);
entry.flMdDat = BigEndianBitConverter.ToUInt32(directoryBlocks, offset + 46);
entry.flNam = new byte[directoryBlocks[offset + 50] + 1];
Array.Copy(directoryBlocks, offset + 50, entry.flNam, 0, entry.flNam.Length);
string lowerFilename = StringHandlers
.PascalToString(entry.flNam, Encoding).ToLowerInvariant().Replace('/', ':');
.PascalToString(entry.flNam, Encoding).ToLowerInvariant().Replace('/', ':');
if(entry.flFlags.HasFlag(MFS_FileFlags.Used) && !idToFilename.ContainsKey(entry.flFlNum) &&
!idToEntry.ContainsKey(entry.flFlNum) && !filenameToId.ContainsKey(lowerFilename) &&
!idToEntry.ContainsKey(entry.flFlNum) && !filenameToId.ContainsKey(lowerFilename) &&
entry.flFlNum > 0)
{
idToEntry.Add(entry.flFlNum, entry);
@@ -104,12 +104,12 @@ namespace DiscImageChef.Filesystems.AppleMFS
StringHandlers.PascalToString(entry.flNam, Encoding).Replace('/', ':'));
filenameToId.Add(lowerFilename, entry.flFlNum);
DicConsole.DebugWriteLine("DEBUG (AppleMFS plugin)", "entry.flFlags = {0}", entry.flFlags);
DicConsole.DebugWriteLine("DEBUG (AppleMFS plugin)", "entry.flTyp = {0}", entry.flTyp);
DicConsole.DebugWriteLine("DEBUG (AppleMFS plugin)", "entry.flFlNum = {0}", entry.flFlNum);
DicConsole.DebugWriteLine("DEBUG (AppleMFS plugin)", "entry.flStBlk = {0}", entry.flStBlk);
DicConsole.DebugWriteLine("DEBUG (AppleMFS plugin)", "entry.flLgLen = {0}", entry.flLgLen);
DicConsole.DebugWriteLine("DEBUG (AppleMFS plugin)", "entry.flPyLen = {0}", entry.flPyLen);
DicConsole.DebugWriteLine("DEBUG (AppleMFS plugin)", "entry.flFlags = {0}", entry.flFlags);
DicConsole.DebugWriteLine("DEBUG (AppleMFS plugin)", "entry.flTyp = {0}", entry.flTyp);
DicConsole.DebugWriteLine("DEBUG (AppleMFS plugin)", "entry.flFlNum = {0}", entry.flFlNum);
DicConsole.DebugWriteLine("DEBUG (AppleMFS plugin)", "entry.flStBlk = {0}", entry.flStBlk);
DicConsole.DebugWriteLine("DEBUG (AppleMFS plugin)", "entry.flLgLen = {0}", entry.flLgLen);
DicConsole.DebugWriteLine("DEBUG (AppleMFS plugin)", "entry.flPyLen = {0}", entry.flPyLen);
DicConsole.DebugWriteLine("DEBUG (AppleMFS plugin)", "entry.flRStBlk = {0}", entry.flRStBlk);
DicConsole.DebugWriteLine("DEBUG (AppleMFS plugin)", "entry.flRLgLen = {0}", entry.flRLgLen);
DicConsole.DebugWriteLine("DEBUG (AppleMFS plugin)", "entry.flRPyLen = {0}", entry.flRPyLen);

View File

@@ -56,7 +56,7 @@ namespace DiscImageChef.Filesystems.AppleMFS
if(fileBlock > entry.flPyLen / volMDB.drAlBlkSiz) return Errno.InvalidArgument;
uint nextBlock = entry.flStBlk;
long relBlock = 0;
long relBlock = 0;
while(true)
{
@@ -89,16 +89,16 @@ namespace DiscImageChef.Filesystems.AppleMFS
MFS_FinderFlags fdFlags = (MFS_FinderFlags)BigEndianBitConverter.ToUInt16(entry.flUsrWds, 0x08);
if(fdFlags.HasFlag(MFS_FinderFlags.kIsAlias)) attributes |= FileAttributes.Alias;
if(fdFlags.HasFlag(MFS_FinderFlags.kHasBundle)) attributes |= FileAttributes.Bundle;
if(fdFlags.HasFlag(MFS_FinderFlags.kIsAlias)) attributes |= FileAttributes.Alias;
if(fdFlags.HasFlag(MFS_FinderFlags.kHasBundle)) attributes |= FileAttributes.Bundle;
if(fdFlags.HasFlag(MFS_FinderFlags.kHasBeenInited)) attributes |= FileAttributes.HasBeenInited;
if(fdFlags.HasFlag(MFS_FinderFlags.kHasCustomIcon)) attributes |= FileAttributes.HasCustomIcon;
if(fdFlags.HasFlag(MFS_FinderFlags.kHasNoINITs)) attributes |= FileAttributes.HasNoINITs;
if(fdFlags.HasFlag(MFS_FinderFlags.kIsInvisible)) attributes |= FileAttributes.Hidden;
if(entry.flFlags.HasFlag(MFS_FileFlags.Locked)) attributes |= FileAttributes.Immutable;
if(fdFlags.HasFlag(MFS_FinderFlags.kIsOnDesk)) attributes |= FileAttributes.IsOnDesk;
if(fdFlags.HasFlag(MFS_FinderFlags.kIsShared)) attributes |= FileAttributes.Shared;
if(fdFlags.HasFlag(MFS_FinderFlags.kIsStationery)) attributes |= FileAttributes.Stationery;
if(fdFlags.HasFlag(MFS_FinderFlags.kHasNoINITs)) attributes |= FileAttributes.HasNoINITs;
if(fdFlags.HasFlag(MFS_FinderFlags.kIsInvisible)) attributes |= FileAttributes.Hidden;
if(entry.flFlags.HasFlag(MFS_FileFlags.Locked)) attributes |= FileAttributes.Immutable;
if(fdFlags.HasFlag(MFS_FinderFlags.kIsOnDesk)) attributes |= FileAttributes.IsOnDesk;
if(fdFlags.HasFlag(MFS_FinderFlags.kIsShared)) attributes |= FileAttributes.Shared;
if(fdFlags.HasFlag(MFS_FinderFlags.kIsStationery)) attributes |= FileAttributes.Stationery;
if(!attributes.HasFlag(FileAttributes.Alias) && !attributes.HasFlag(FileAttributes.Bundle) &&
!attributes.HasFlag(FileAttributes.Stationery)) attributes |= FileAttributes.File;
@@ -113,15 +113,18 @@ namespace DiscImageChef.Filesystems.AppleMFS
if(!mounted) return Errno.AccessDenied;
byte[] file;
Errno error = Errno.NoError;
Errno error = Errno.NoError;
if(debug && string.Compare(path, "$", StringComparison.InvariantCulture) == 0) file = directoryBlocks;
else if(debug && string.Compare(path, "$Boot", StringComparison.InvariantCulture) == 0 && bootBlocks != null
) file = bootBlocks;
else if(debug && string.Compare(path, "$Boot", StringComparison.InvariantCulture) == 0 &&
bootBlocks != null)
file = bootBlocks;
else if(debug && string.Compare(path, "$Bitmap", StringComparison.InvariantCulture) == 0)
file = blockMapBytes;
file = blockMapBytes;
else if(debug && string.Compare(path, "$MDB", StringComparison.InvariantCulture) == 0) file = mdbBlocks;
else error = ReadFile(path, out file, false, false);
else
error =
ReadFile(path, out file, false, false);
if(error != Errno.NoError) return error;
@@ -151,20 +154,20 @@ namespace DiscImageChef.Filesystems.AppleMFS
if(pathElements.Length != 1) return Errno.NotSupported;
if(debug)
if(string.Compare(path, "$", StringComparison.InvariantCulture) == 0 ||
string.Compare(path, "$Boot", StringComparison.InvariantCulture) == 0 ||
if(string.Compare(path, "$", StringComparison.InvariantCulture) == 0 ||
string.Compare(path, "$Boot", StringComparison.InvariantCulture) == 0 ||
string.Compare(path, "$Bitmap", StringComparison.InvariantCulture) == 0 ||
string.Compare(path, "$MDB", StringComparison.InvariantCulture) == 0)
string.Compare(path, "$MDB", StringComparison.InvariantCulture) == 0)
{
stat = new FileEntryInfo
{
BlockSize = device.Info.SectorSize,
DeviceNo = 0,
GID = 0,
Inode = 0,
Links = 1,
Mode = 0x124,
UID = 0,
BlockSize = device.Info.SectorSize,
DeviceNo = 0,
GID = 0,
Inode = 0,
Links = 1,
Mode = 0x124,
UID = 0,
Attributes = FileAttributes.System
};
@@ -202,18 +205,18 @@ namespace DiscImageChef.Filesystems.AppleMFS
stat = new FileEntryInfo
{
Attributes = attr,
Blocks = entry.flLgLen / volMDB.drAlBlkSiz,
BlockSize = volMDB.drAlBlkSiz,
CreationTime = DateHandlers.MacToDateTime(entry.flCrDat),
DeviceNo = 0,
GID = 0,
Inode = entry.flFlNum,
Attributes = attr,
Blocks = entry.flLgLen / volMDB.drAlBlkSiz,
BlockSize = volMDB.drAlBlkSiz,
CreationTime = DateHandlers.MacToDateTime(entry.flCrDat),
DeviceNo = 0,
GID = 0,
Inode = entry.flFlNum,
LastWriteTime = DateHandlers.MacToDateTime(entry.flMdDat),
Length = entry.flPyLen,
Links = 1,
Mode = 0x124,
UID = 0
Length = entry.flPyLen,
Links = 1,
Mode = 0x124,
UID = 0
};
return Errno.NoError;
@@ -291,7 +294,8 @@ namespace DiscImageChef.Filesystems.AppleMFS
else
{
if(resourceFork)
if(ms.Length < entry.flRLgLen) buf = ms.ToArray();
if(ms.Length < entry.flRLgLen)
buf = ms.ToArray();
else
{
buf = new byte[entry.flRLgLen];

View File

@@ -57,39 +57,39 @@ namespace DiscImageChef.Filesystems.AppleMFS
}
public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
Encoding encoding)
Encoding encoding)
{
Encoding = encoding ?? new MacRoman();
Encoding = encoding ?? new MacRoman();
information = "";
StringBuilder sb = new StringBuilder();
MFS_MasterDirectoryBlock mdb = new MFS_MasterDirectoryBlock();
MFS_BootBlock bb = new MFS_BootBlock();
MFS_BootBlock bb = new MFS_BootBlock();
byte[] pString = new byte[16];
byte[] mdbSector = imagePlugin.ReadSector(2 + partition.Start);
byte[] bbSector = imagePlugin.ReadSector(0 + partition.Start);
byte[] bbSector = imagePlugin.ReadSector(0 + partition.Start);
BigEndianBitConverter.IsLittleEndian = BitConverter.IsLittleEndian;
mdb.drSigWord = BigEndianBitConverter.ToUInt16(mdbSector, 0x000);
if(mdb.drSigWord != MFS_MAGIC) return;
mdb.drCrDate = BigEndianBitConverter.ToUInt32(mdbSector, 0x002);
mdb.drLsBkUp = BigEndianBitConverter.ToUInt32(mdbSector, 0x006);
mdb.drAtrb = BigEndianBitConverter.ToUInt16(mdbSector, 0x00A);
mdb.drNmFls = BigEndianBitConverter.ToUInt16(mdbSector, 0x00C);
mdb.drDirSt = BigEndianBitConverter.ToUInt16(mdbSector, 0x00E);
mdb.drBlLen = BigEndianBitConverter.ToUInt16(mdbSector, 0x010);
mdb.drCrDate = BigEndianBitConverter.ToUInt32(mdbSector, 0x002);
mdb.drLsBkUp = BigEndianBitConverter.ToUInt32(mdbSector, 0x006);
mdb.drAtrb = BigEndianBitConverter.ToUInt16(mdbSector, 0x00A);
mdb.drNmFls = BigEndianBitConverter.ToUInt16(mdbSector, 0x00C);
mdb.drDirSt = BigEndianBitConverter.ToUInt16(mdbSector, 0x00E);
mdb.drBlLen = BigEndianBitConverter.ToUInt16(mdbSector, 0x010);
mdb.drNmAlBlks = BigEndianBitConverter.ToUInt16(mdbSector, 0x012);
mdb.drAlBlkSiz = BigEndianBitConverter.ToUInt32(mdbSector, 0x014);
mdb.drClpSiz = BigEndianBitConverter.ToUInt32(mdbSector, 0x018);
mdb.drAlBlSt = BigEndianBitConverter.ToUInt16(mdbSector, 0x01C);
mdb.drNxtFNum = BigEndianBitConverter.ToUInt32(mdbSector, 0x01E);
mdb.drFreeBks = BigEndianBitConverter.ToUInt16(mdbSector, 0x022);
mdb.drVNSiz = mdbSector[0x024];
mdb.drClpSiz = BigEndianBitConverter.ToUInt32(mdbSector, 0x018);
mdb.drAlBlSt = BigEndianBitConverter.ToUInt16(mdbSector, 0x01C);
mdb.drNxtFNum = BigEndianBitConverter.ToUInt32(mdbSector, 0x01E);
mdb.drFreeBks = BigEndianBitConverter.ToUInt16(mdbSector, 0x022);
mdb.drVNSiz = mdbSector[0x024];
byte[] variableSize = new byte[mdb.drVNSiz + 1];
Array.Copy(mdbSector, 0x024, variableSize, 0, mdb.drVNSiz + 1);
mdb.drVN = StringHandlers.PascalToString(variableSize, Encoding);
@@ -98,8 +98,8 @@ namespace DiscImageChef.Filesystems.AppleMFS
if(bb.signature == MFSBB_MAGIC)
{
bb.branch = BigEndianBitConverter.ToUInt32(bbSector, 0x002);
bb.boot_flags = bbSector[0x006];
bb.branch = BigEndianBitConverter.ToUInt32(bbSector, 0x002);
bb.boot_flags = bbSector[0x006];
bb.boot_version = bbSector[0x007];
bb.sec_sv_pages = BigEndianBitConverter.ToInt16(bbSector, 0x008);
@@ -119,11 +119,11 @@ namespace DiscImageChef.Filesystems.AppleMFS
Array.Copy(mdbSector, 0x06A, pString, 0, 16);
bb.clipbrd_name = StringHandlers.PascalToString(pString, Encoding);
bb.max_files = BigEndianBitConverter.ToUInt16(bbSector, 0x07A);
bb.max_files = BigEndianBitConverter.ToUInt16(bbSector, 0x07A);
bb.queue_size = BigEndianBitConverter.ToUInt16(bbSector, 0x07C);
bb.heap_128k = BigEndianBitConverter.ToUInt32(bbSector, 0x07E);
bb.heap_256k = BigEndianBitConverter.ToUInt32(bbSector, 0x082);
bb.heap_512k = BigEndianBitConverter.ToUInt32(bbSector, 0x086);
bb.heap_128k = BigEndianBitConverter.ToUInt32(bbSector, 0x07E);
bb.heap_256k = BigEndianBitConverter.ToUInt32(bbSector, 0x082);
bb.heap_512k = BigEndianBitConverter.ToUInt32(bbSector, 0x086);
}
else bb.signature = 0x0000;
@@ -132,7 +132,7 @@ namespace DiscImageChef.Filesystems.AppleMFS
sb.AppendLine("Master Directory Block:");
sb.AppendFormat("Creation date: {0}", DateHandlers.MacToDateTime(mdb.drCrDate)).AppendLine();
sb.AppendFormat("Last backup date: {0}", DateHandlers.MacToDateTime(mdb.drLsBkUp)).AppendLine();
if((mdb.drAtrb & 0x80) == 0x80) sb.AppendLine("Volume is locked by hardware.");
if((mdb.drAtrb & 0x80) == 0x80) sb.AppendLine("Volume is locked by hardware.");
if((mdb.drAtrb & 0x8000) == 0x8000) sb.AppendLine("Volume is locked by software.");
sb.AppendFormat("{0} files on volume", mdb.drNmFls).AppendLine();
sb.AppendFormat("First directory sector: {0}", mdb.drDirSt).AppendLine();
@@ -154,7 +154,7 @@ namespace DiscImageChef.Filesystems.AppleMFS
if((bb.boot_flags & 0x80) == 0x80) sb.AppendLine("Boot block is in new unknown format.");
else
{
if(bb.sec_sv_pages > 0) sb.AppendLine("Allocate secondary sound buffer at boot.");
if(bb.sec_sv_pages > 0) sb.AppendLine("Allocate secondary sound buffer at boot.");
else if(bb.sec_sv_pages < 0) sb.AppendLine("Allocate secondary sound and video buffers at boot.");
sb.AppendFormat("System filename: {0}", bb.system_name).AppendLine();
@@ -178,23 +178,25 @@ namespace DiscImageChef.Filesystems.AppleMFS
XmlFsType = new FileSystemType();
if(mdb.drLsBkUp > 0)
{
XmlFsType.BackupDate = DateHandlers.MacToDateTime(mdb.drLsBkUp);
XmlFsType.BackupDate = DateHandlers.MacToDateTime(mdb.drLsBkUp);
XmlFsType.BackupDateSpecified = true;
}
XmlFsType.Bootable = bb.signature == MFSBB_MAGIC;
XmlFsType.Clusters = mdb.drNmAlBlks;
XmlFsType.Bootable = bb.signature == MFSBB_MAGIC;
XmlFsType.Clusters = mdb.drNmAlBlks;
XmlFsType.ClusterSize = (int)mdb.drAlBlkSiz;
if(mdb.drCrDate > 0)
{
XmlFsType.CreationDate = DateHandlers.MacToDateTime(mdb.drCrDate);
XmlFsType.CreationDate = DateHandlers.MacToDateTime(mdb.drCrDate);
XmlFsType.CreationDateSpecified = true;
}
XmlFsType.Files = mdb.drNmFls;
XmlFsType.FilesSpecified = true;
XmlFsType.FreeClusters = mdb.drFreeBks;
XmlFsType.Files = mdb.drNmFls;
XmlFsType.FilesSpecified = true;
XmlFsType.FreeClusters = mdb.drFreeBks;
XmlFsType.FreeClustersSpecified = true;
XmlFsType.Type = "MFS";
XmlFsType.VolumeName = mdb.drVN;
XmlFsType.Type = "MFS";
XmlFsType.VolumeName = mdb.drVN;
}
}
}

View File

@@ -124,26 +124,26 @@ namespace DiscImageChef.Filesystems.AppleMFS
enum MFS_FileFlags : byte
{
Locked = 0x01,
Used = 0x80
Used = 0x80
}
[Flags]
enum MFS_FinderFlags : ushort
{
kIsOnDesk = 0x0001,
kColor = 0x000E,
kIsOnDesk = 0x0001,
kColor = 0x000E,
kRequireSwitchLaunch = 0x0020,
kIsShared = 0x0040,
kHasNoINITs = 0x0080,
kHasBeenInited = 0x0100,
kHasCustomIcon = 0x0400,
kLetter = 0x0200,
kChanged = 0x0200,
kIsStationery = 0x0800,
kNameLocked = 0x1000,
kHasBundle = 0x2000,
kIsInvisible = 0x4000,
kIsAlias = 0x8000
kIsShared = 0x0040,
kHasNoINITs = 0x0080,
kHasBeenInited = 0x0100,
kHasCustomIcon = 0x0400,
kLetter = 0x0200,
kChanged = 0x0200,
kIsStationery = 0x0800,
kNameLocked = 0x1000,
kHasBundle = 0x2000,
kIsInvisible = 0x4000,
kIsAlias = 0x8000
}
struct MFS_Point
@@ -154,11 +154,11 @@ namespace DiscImageChef.Filesystems.AppleMFS
struct MFS_FinderInfo
{
public uint fdType;
public uint fdCreator;
public uint fdType;
public uint fdCreator;
public MFS_FinderFlags fdFlags;
public MFS_Point fdLocation;
public short fdFldr;
public MFS_Point fdLocation;
public short fdFldr;
}
struct MFS_FileEntry

View File

@@ -45,9 +45,9 @@ namespace DiscImageChef.Filesystems.AppleMFS
public Errno Mount(IMediaImage imagePlugin, Partition partition, Encoding encoding,
Dictionary<string, string> options)
{
device = imagePlugin;
partitionStart = partition.Start;
Encoding = encoding ?? Encoding.GetEncoding("macintosh");
device = imagePlugin;
partitionStart = partition.Start;
Encoding = encoding ?? Encoding.GetEncoding("macintosh");
if(options == null) options = GetDefaultOptions();
if(options.TryGetValue("debug", out string debugString)) bool.TryParse(debugString, out debug);
volMDB = new MFS_MasterDirectoryBlock();
@@ -60,64 +60,63 @@ namespace DiscImageChef.Filesystems.AppleMFS
volMDB.drSigWord = BigEndianBitConverter.ToUInt16(mdbBlocks, 0x000);
if(volMDB.drSigWord != MFS_MAGIC) return Errno.InvalidArgument;
volMDB.drCrDate = BigEndianBitConverter.ToUInt32(mdbBlocks, 0x002);
volMDB.drLsBkUp = BigEndianBitConverter.ToUInt32(mdbBlocks, 0x006);
volMDB.drAtrb = BigEndianBitConverter.ToUInt16(mdbBlocks, 0x00A);
volMDB.drNmFls = BigEndianBitConverter.ToUInt16(mdbBlocks, 0x00C);
volMDB.drDirSt = BigEndianBitConverter.ToUInt16(mdbBlocks, 0x00E);
volMDB.drBlLen = BigEndianBitConverter.ToUInt16(mdbBlocks, 0x010);
volMDB.drNmAlBlks = BigEndianBitConverter.ToUInt16(mdbBlocks, 0x012);
volMDB.drAlBlkSiz = BigEndianBitConverter.ToUInt32(mdbBlocks, 0x014);
volMDB.drClpSiz = BigEndianBitConverter.ToUInt32(mdbBlocks, 0x018);
volMDB.drAlBlSt = BigEndianBitConverter.ToUInt16(mdbBlocks, 0x01C);
volMDB.drNxtFNum = BigEndianBitConverter.ToUInt32(mdbBlocks, 0x01E);
volMDB.drFreeBks = BigEndianBitConverter.ToUInt16(mdbBlocks, 0x022);
volMDB.drVNSiz = mdbBlocks[0x024];
byte[] variableSize = new byte[volMDB.drVNSiz + 1];
volMDB.drCrDate = BigEndianBitConverter.ToUInt32(mdbBlocks, 0x002);
volMDB.drLsBkUp = BigEndianBitConverter.ToUInt32(mdbBlocks, 0x006);
volMDB.drAtrb = BigEndianBitConverter.ToUInt16(mdbBlocks, 0x00A);
volMDB.drNmFls = BigEndianBitConverter.ToUInt16(mdbBlocks, 0x00C);
volMDB.drDirSt = BigEndianBitConverter.ToUInt16(mdbBlocks, 0x00E);
volMDB.drBlLen = BigEndianBitConverter.ToUInt16(mdbBlocks, 0x010);
volMDB.drNmAlBlks = BigEndianBitConverter.ToUInt16(mdbBlocks, 0x012);
volMDB.drAlBlkSiz = BigEndianBitConverter.ToUInt32(mdbBlocks, 0x014);
volMDB.drClpSiz = BigEndianBitConverter.ToUInt32(mdbBlocks, 0x018);
volMDB.drAlBlSt = BigEndianBitConverter.ToUInt16(mdbBlocks, 0x01C);
volMDB.drNxtFNum = BigEndianBitConverter.ToUInt32(mdbBlocks, 0x01E);
volMDB.drFreeBks = BigEndianBitConverter.ToUInt16(mdbBlocks, 0x022);
volMDB.drVNSiz = mdbBlocks[0x024];
byte[] variableSize = new byte[volMDB.drVNSiz + 1];
Array.Copy(mdbBlocks, 0x024, variableSize, 0, volMDB.drVNSiz + 1);
volMDB.drVN = StringHandlers.PascalToString(variableSize, Encoding);
directoryBlocks = device.ReadSectors(volMDB.drDirSt + partitionStart, volMDB.drBlLen);
int bytesInBlockMap = volMDB.drNmAlBlks * 12 / 8 + volMDB.drNmAlBlks * 12 % 8;
directoryBlocks = device.ReadSectors(volMDB.drDirSt + partitionStart, volMDB.drBlLen);
int bytesInBlockMap = volMDB.drNmAlBlks * 12 / 8 + volMDB.drNmAlBlks * 12 % 8;
const int BYTES_BEFORE_BLOCK_MAP = 64;
int bytesInWholeMdb = bytesInBlockMap + BYTES_BEFORE_BLOCK_MAP;
int sectorsInWholeMdb = bytesInWholeMdb / (int)device.Info.SectorSize +
bytesInWholeMdb % (int)device.Info.SectorSize;
int bytesInWholeMdb = bytesInBlockMap + BYTES_BEFORE_BLOCK_MAP;
int sectorsInWholeMdb = bytesInWholeMdb / (int)device.Info.SectorSize +
bytesInWholeMdb % (int)device.Info.SectorSize;
byte[] wholeMdb = device.ReadSectors(partitionStart + 2, (uint)sectorsInWholeMdb);
blockMapBytes = new byte[bytesInBlockMap];
blockMapBytes = new byte[bytesInBlockMap];
Array.Copy(wholeMdb, BYTES_BEFORE_BLOCK_MAP, blockMapBytes, 0, blockMapBytes.Length);
int offset = 0;
blockMap = new uint[volMDB.drNmAlBlks + 2 + 1];
for(int i = 2; i < volMDB.drNmAlBlks + 2; i += 8)
blockMap = new uint[volMDB.drNmAlBlks + 2 + 1];
for(int i = 2; i < volMDB.drNmAlBlks + 2; i += 8)
{
uint tmp1 = 0;
uint tmp2 = 0;
uint tmp3 = 0;
if(offset + 4 <= blockMapBytes.Length)
tmp1 = BigEndianBitConverter.ToUInt32(blockMapBytes, offset);
if(offset + 4 + 4 <= blockMapBytes.Length)
if(offset + 4 <= blockMapBytes.Length) tmp1 = BigEndianBitConverter.ToUInt32(blockMapBytes, offset);
if(offset + 4 + 4 <= blockMapBytes.Length)
tmp2 = BigEndianBitConverter.ToUInt32(blockMapBytes, offset + 4);
if(offset + 8 + 4 <= blockMapBytes.Length)
if(offset + 8 + 4 <= blockMapBytes.Length)
tmp3 = BigEndianBitConverter.ToUInt32(blockMapBytes, offset + 8);
if(i < blockMap.Length) blockMap[i] = (tmp1 & 0xFFF00000) >> 20;
if(i + 2 < blockMap.Length) blockMap[i + 1] = (tmp1 & 0xFFF00) >> 8;
if(i + 3 < blockMap.Length) blockMap[i + 2] = ((tmp1 & 0xFF) << 4) + ((tmp2 & 0xF0000000) >> 28);
if(i + 4 < blockMap.Length) blockMap[i + 3] = (tmp2 & 0xFFF0000) >> 16;
if(i + 5 < blockMap.Length) blockMap[i + 4] = (tmp2 & 0xFFF0) >> 4;
if(i + 6 < blockMap.Length) blockMap[i + 5] = ((tmp2 & 0xF) << 8) + ((tmp3 & 0xFF000000) >> 24);
if(i + 7 < blockMap.Length) blockMap[i + 6] = (tmp3 & 0xFFF000) >> 12;
if(i + 8 < blockMap.Length) blockMap[i + 7] = tmp3 & 0xFFF;
if(i < blockMap.Length) blockMap[i] = (tmp1 & 0xFFF00000) >> 20;
if(i + 2 < blockMap.Length) blockMap[i + 1] = (tmp1 & 0xFFF00) >> 8;
if(i + 3 < blockMap.Length) blockMap[i + 2] = ((tmp1 & 0xFF) << 4) + ((tmp2 & 0xF0000000) >> 28);
if(i + 4 < blockMap.Length) blockMap[i + 3] = (tmp2 & 0xFFF0000) >> 16;
if(i + 5 < blockMap.Length) blockMap[i + 4] = (tmp2 & 0xFFF0) >> 4;
if(i + 6 < blockMap.Length) blockMap[i + 5] = ((tmp2 & 0xF) << 8) + ((tmp3 & 0xFF000000) >> 24);
if(i + 7 < blockMap.Length) blockMap[i + 6] = (tmp3 & 0xFFF000) >> 12;
if(i + 8 < blockMap.Length) blockMap[i + 7] = tmp3 & 0xFFF;
offset += 12;
}
if(device.Info.ReadableSectorTags.Contains(SectorTagType.AppleSectorTag))
{
mdbTags = device.ReadSectorTag(2 + partitionStart, SectorTagType.AppleSectorTag);
bootTags = device.ReadSectorTag(0 + partitionStart, SectorTagType.AppleSectorTag);
mdbTags = device.ReadSectorTag(2 + partitionStart, SectorTagType.AppleSectorTag);
bootTags = device.ReadSectorTag(0 + partitionStart, SectorTagType.AppleSectorTag);
directoryTags = device.ReadSectorsTag(volMDB.drDirSt + partitionStart, volMDB.drBlLen,
SectorTagType.AppleSectorTag);
bitmapTags = device.ReadSectorsTag(partitionStart + 2, (uint)sectorsInWholeMdb,

View File

@@ -51,10 +51,10 @@ namespace DiscImageChef.Filesystems.AppleMFS
xattrs = new List<string>();
if(debug)
if(string.Compare(path, "$", StringComparison.InvariantCulture) == 0 ||
if(string.Compare(path, "$", StringComparison.InvariantCulture) == 0 ||
string.Compare(path, "$Bitmap", StringComparison.InvariantCulture) == 0 ||
string.Compare(path, "$Boot", StringComparison.InvariantCulture) == 0 ||
string.Compare(path, "$MDB", StringComparison.InvariantCulture) == 0)
string.Compare(path, "$Boot", StringComparison.InvariantCulture) == 0 ||
string.Compare(path, "$MDB", StringComparison.InvariantCulture) == 0)
{
if(device.Info.ReadableSectorTags.Contains(SectorTagType.AppleSectorTag))
xattrs.Add("com.apple.macintosh.tags");
@@ -91,10 +91,10 @@ namespace DiscImageChef.Filesystems.AppleMFS
if(pathElements.Length != 1) return Errno.NotSupported;
if(debug)
if(string.Compare(path, "$", StringComparison.InvariantCulture) == 0 ||
if(string.Compare(path, "$", StringComparison.InvariantCulture) == 0 ||
string.Compare(path, "$Bitmap", StringComparison.InvariantCulture) == 0 ||
string.Compare(path, "$Boot", StringComparison.InvariantCulture) == 0 ||
string.Compare(path, "$MDB", StringComparison.InvariantCulture) == 0)
string.Compare(path, "$Boot", StringComparison.InvariantCulture) == 0 ||
string.Compare(path, "$MDB", StringComparison.InvariantCulture) == 0)
if(device.Info.ReadableSectorTags.Contains(SectorTagType.AppleSectorTag) &&
string.Compare(xattr, "com.apple.macintosh.tags", StringComparison.InvariantCulture) == 0)
{
@@ -126,7 +126,8 @@ namespace DiscImageChef.Filesystems.AppleMFS
return Errno.NoError;
}
}
else return Errno.NoSuchExtendedAttribute;
else
return Errno.NoSuchExtendedAttribute;
Errno error;
@@ -134,14 +135,14 @@ namespace DiscImageChef.Filesystems.AppleMFS
if(!idToEntry.TryGetValue(fileId, out MFS_FileEntry entry)) return Errno.NoSuchFile;
if(entry.flRLgLen > 0 &&
if(entry.flRLgLen > 0 &&
string.Compare(xattr, "com.apple.ResourceFork", StringComparison.InvariantCulture) == 0)
{
error = ReadFile(path, out buf, true, false);
return error;
}
if(entry.flRLgLen > 0 &&
if(entry.flRLgLen > 0 &&
string.Compare(xattr, "com.apple.ResourceFork.tags", StringComparison.InvariantCulture) == 0)
{
error = ReadFile(path, out buf, true, true);

View File

@@ -47,25 +47,25 @@ namespace DiscImageChef.Filesystems
const uint AFS_MAGIC3 = 0x15B6830E;
// Common constants
const uint AFS_SUPERBLOCK_SIZE = 1024;
const uint AFS_BOOTBLOCK_SIZE = AFS_SUPERBLOCK_SIZE;
const uint AFS_BOOTBLOCK_SIZE = AFS_SUPERBLOCK_SIZE;
public FileSystemType XmlFsType { get; private set; }
public Encoding Encoding { get; private set; }
public string Name => "AtheOS Filesystem";
public Guid Id => new Guid("AAB2C4F1-DC07-49EE-A948-576CC51B58C5");
public Encoding Encoding { get; private set; }
public string Name => "AtheOS Filesystem";
public Guid Id => new Guid("AAB2C4F1-DC07-49EE-A948-576CC51B58C5");
public bool Identify(IMediaImage imagePlugin, Partition partition)
{
ulong sector = AFS_BOOTBLOCK_SIZE / imagePlugin.Info.SectorSize;
uint offset = AFS_BOOTBLOCK_SIZE % imagePlugin.Info.SectorSize;
uint run = 1;
uint offset = AFS_BOOTBLOCK_SIZE % imagePlugin.Info.SectorSize;
uint run = 1;
if(imagePlugin.Info.SectorSize < AFS_SUPERBLOCK_SIZE)
run = AFS_SUPERBLOCK_SIZE / imagePlugin.Info.SectorSize;
if(sector + partition.Start >= partition.End) return false;
byte[] tmp = imagePlugin.ReadSectors(sector + partition.Start, run);
byte[] tmp = imagePlugin.ReadSectors(sector + partition.Start, run);
byte[] sbSector = new byte[AFS_SUPERBLOCK_SIZE];
Array.Copy(tmp, offset, sbSector, 0, AFS_SUPERBLOCK_SIZE);
@@ -75,21 +75,21 @@ namespace DiscImageChef.Filesystems
}
public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
Encoding encoding)
Encoding encoding)
{
Encoding = encoding ?? Encoding.GetEncoding("iso-8859-15");
Encoding = encoding ?? Encoding.GetEncoding("iso-8859-15");
information = "";
StringBuilder sb = new StringBuilder();
ulong sector = AFS_BOOTBLOCK_SIZE / imagePlugin.Info.SectorSize;
uint offset = AFS_BOOTBLOCK_SIZE % imagePlugin.Info.SectorSize;
uint run = 1;
uint offset = AFS_BOOTBLOCK_SIZE % imagePlugin.Info.SectorSize;
uint run = 1;
if(imagePlugin.Info.SectorSize < AFS_SUPERBLOCK_SIZE)
run = AFS_SUPERBLOCK_SIZE / imagePlugin.Info.SectorSize;
byte[] tmp = imagePlugin.ReadSectors(sector + partition.Start, run);
byte[] tmp = imagePlugin.ReadSectors(sector + partition.Start, run);
byte[] sbSector = new byte[AFS_SUPERBLOCK_SIZE];
Array.Copy(tmp, offset, sbSector, 0, AFS_SUPERBLOCK_SIZE);
@@ -118,17 +118,17 @@ namespace DiscImageChef.Filesystems
sb.AppendFormat("Journal starts in byte {0} and has {1} bytes in {2} blocks", afsSb.log_start,
afsSb.log_size, afsSb.log_valid_blocks).AppendLine();
sb
.AppendFormat("Root folder's i-node resides in block {0} of allocation group {1} and runs for {2} blocks ({3} bytes)",
afsSb.root_dir_start, afsSb.root_dir_ag, afsSb.root_dir_len,
afsSb.root_dir_len * afsSb.block_size).AppendLine();
.AppendFormat("Root folder's i-node resides in block {0} of allocation group {1} and runs for {2} blocks ({3} bytes)",
afsSb.root_dir_start, afsSb.root_dir_ag, afsSb.root_dir_len,
afsSb.root_dir_len * afsSb.block_size).AppendLine();
sb
.AppendFormat("Directory containing files scheduled for deletion's i-node resides in block {0} of allocation group {1} and runs for {2} blocks ({3} bytes)",
afsSb.deleted_start, afsSb.deleted_ag, afsSb.deleted_len,
afsSb.deleted_len * afsSb.block_size).AppendLine();
.AppendFormat("Directory containing files scheduled for deletion's i-node resides in block {0} of allocation group {1} and runs for {2} blocks ({3} bytes)",
afsSb.deleted_start, afsSb.deleted_ag, afsSb.deleted_len,
afsSb.deleted_len * afsSb.block_size).AppendLine();
sb
.AppendFormat("Indices' i-node resides in block {0} of allocation group {1} and runs for {2} blocks ({3} bytes)",
afsSb.indices_start, afsSb.indices_ag, afsSb.indices_len,
afsSb.indices_len * afsSb.block_size).AppendLine();
.AppendFormat("Indices' i-node resides in block {0} of allocation group {1} and runs for {2} blocks ({3} bytes)",
afsSb.indices_start, afsSb.indices_ag, afsSb.indices_len,
afsSb.indices_len * afsSb.block_size).AppendLine();
sb.AppendFormat("{0} blocks for bootloader ({1} bytes)", afsSb.boot_size,
afsSb.boot_size * afsSb.block_size).AppendLine();
@@ -136,13 +136,13 @@ namespace DiscImageChef.Filesystems
XmlFsType = new FileSystemType
{
Clusters = afsSb.num_blocks,
ClusterSize = (int)afsSb.block_size,
Dirty = false,
FreeClusters = afsSb.num_blocks - afsSb.used_blocks,
Clusters = afsSb.num_blocks,
ClusterSize = (int)afsSb.block_size,
Dirty = false,
FreeClusters = afsSb.num_blocks - afsSb.used_blocks,
FreeClustersSpecified = true,
Type = "AtheOS filesystem",
VolumeName = StringHandlers.CToString(afsSb.name, Encoding)
Type = "AtheOS filesystem",
VolumeName = StringHandlers.CToString(afsSb.name, Encoding)
};
}
@@ -153,7 +153,8 @@ namespace DiscImageChef.Filesystems
struct AtheosSuperBlock
{
/// <summary>0x000, Volume name, 32 bytes</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] public byte[] name;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public byte[] name;
/// <summary>0x020, "AFS1", 0x41465331</summary>
public uint magic1;
/// <summary>0x024, "BIGE", 0x42494745</summary>

View File

@@ -55,9 +55,9 @@ namespace DiscImageChef.Filesystems
const uint BEFS_DIRTY = 0x44495254;
public FileSystemType XmlFsType { get; private set; }
public Encoding Encoding { get; private set; }
public string Name => "Be Filesystem";
public Guid Id => new Guid("dc8572b3-b6ad-46e4-8de9-cbe123ff6672");
public Encoding Encoding { get; private set; }
public string Name => "Be Filesystem";
public Guid Id => new Guid("dc8572b3-b6ad-46e4-8de9-cbe123ff6672");
public bool Identify(IMediaImage imagePlugin, Partition partition)
{
@@ -65,14 +65,14 @@ namespace DiscImageChef.Filesystems
byte[] sbSector = imagePlugin.ReadSector(0 + partition.Start);
uint magic = BitConverter.ToUInt32(sbSector, 0x20);
uint magic = BitConverter.ToUInt32(sbSector, 0x20);
uint magicBe = BigEndianBitConverter.ToUInt32(sbSector, 0x20);
if(magic == BEFS_MAGIC1 || magicBe == BEFS_MAGIC1) return true;
if(sbSector.Length >= 0x400)
{
magic = BitConverter.ToUInt32(sbSector, 0x220);
magic = BitConverter.ToUInt32(sbSector, 0x220);
magicBe = BigEndianBitConverter.ToUInt32(sbSector, 0x220);
}
@@ -80,16 +80,16 @@ namespace DiscImageChef.Filesystems
sbSector = imagePlugin.ReadSector(1 + partition.Start);
magic = BitConverter.ToUInt32(sbSector, 0x20);
magic = BitConverter.ToUInt32(sbSector, 0x20);
magicBe = BigEndianBitConverter.ToUInt32(sbSector, 0x20);
return magic == BEFS_MAGIC1 || magicBe == BEFS_MAGIC1;
}
public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
Encoding encoding)
Encoding encoding)
{
Encoding = encoding ?? Encoding.GetEncoding("iso-8859-15");
Encoding = encoding ?? Encoding.GetEncoding("iso-8859-15");
information = "";
StringBuilder sb = new StringBuilder();
@@ -105,7 +105,7 @@ namespace DiscImageChef.Filesystems
littleEndian = besb.magic1 == BEFS_CIGAM1;
else
{
sbSector = imagePlugin.ReadSector(1 + partition.Start);
sbSector = imagePlugin.ReadSector(1 + partition.Start);
besb.magic1 = BigEndianBitConverter.ToUInt32(sbSector, 0x20);
if(besb.magic1 == BEFS_MAGIC1 || besb.magic1 == BEFS_CIGAM1) // There is a boot sector
@@ -118,7 +118,7 @@ namespace DiscImageChef.Filesystems
if(besb.magic1 == BEFS_MAGIC1 || besb.magic1 == BEFS_CIGAM1) // There is a boot sector
{
littleEndian = besb.magic1 == BEFS_CIGAM1;
sbSector = new byte[0x200];
sbSector = new byte[0x200];
Array.Copy(temp, 0x200, sbSector, 0, 0x200);
}
else return;
@@ -136,8 +136,10 @@ namespace DiscImageChef.Filesystems
sb.AppendLine(littleEndian ? "Little-endian BeFS" : "Big-endian BeFS");
if(besb.magic1 != BEFS_MAGIC1 || besb.fs_byte_order != BEFS_ENDIAN || besb.magic2 != BEFS_MAGIC2 ||
besb.magic3 != BEFS_MAGIC3 || besb.root_dir_len != 1 || besb.indices_len != 1 ||
if(besb.magic1 != BEFS_MAGIC1 || besb.fs_byte_order != BEFS_ENDIAN ||
besb.magic2 != BEFS_MAGIC2 ||
besb.magic3 != BEFS_MAGIC3 || besb.root_dir_len != 1 ||
besb.indices_len != 1 ||
1 << (int)besb.block_shift != besb.block_size)
{
sb.AppendLine("Superblock seems corrupt, following information may be incorrect");
@@ -181,25 +183,25 @@ namespace DiscImageChef.Filesystems
sb.AppendFormat("Journal starts in byte {0} and ends in byte {1}", besb.log_start, besb.log_end)
.AppendLine();
sb
.AppendFormat("Root folder's i-node resides in block {0} of allocation group {1} and runs for {2} blocks ({3} bytes)",
besb.root_dir_start, besb.root_dir_ag, besb.root_dir_len,
besb.root_dir_len * besb.block_size).AppendLine();
.AppendFormat("Root folder's i-node resides in block {0} of allocation group {1} and runs for {2} blocks ({3} bytes)",
besb.root_dir_start, besb.root_dir_ag, besb.root_dir_len,
besb.root_dir_len * besb.block_size).AppendLine();
sb
.AppendFormat("Indices' i-node resides in block {0} of allocation group {1} and runs for {2} blocks ({3} bytes)",
besb.indices_start, besb.indices_ag, besb.indices_len, besb.indices_len * besb.block_size)
.AppendLine();
.AppendFormat("Indices' i-node resides in block {0} of allocation group {1} and runs for {2} blocks ({3} bytes)",
besb.indices_start, besb.indices_ag, besb.indices_len, besb.indices_len * besb.block_size)
.AppendLine();
information = sb.ToString();
XmlFsType = new FileSystemType
{
Clusters = besb.num_blocks,
ClusterSize = (int)besb.block_size,
Dirty = besb.flags == BEFS_DIRTY,
FreeClusters = besb.num_blocks - besb.used_blocks,
Clusters = besb.num_blocks,
ClusterSize = (int)besb.block_size,
Dirty = besb.flags == BEFS_DIRTY,
FreeClusters = besb.num_blocks - besb.used_blocks,
FreeClustersSpecified = true,
Type = "BeFS",
VolumeName = StringHandlers.CToString(besb.name, Encoding)
Type = "BeFS",
VolumeName = StringHandlers.CToString(besb.name, Encoding)
};
}
@@ -210,7 +212,8 @@ namespace DiscImageChef.Filesystems
struct BeSuperBlock
{
/// <summary>0x000, Volume name, 32 bytes</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] public byte[] name;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public byte[] name;
/// <summary>0x020, "BFS1", 0x42465331</summary>
public uint magic1;
/// <summary>0x024, "BIGE", 0x42494745</summary>

View File

@@ -48,20 +48,20 @@ namespace DiscImageChef.Filesystems
const ulong BTRFS_MAGIC = 0x4D5F53665248425F;
public FileSystemType XmlFsType { get; private set; }
public Encoding Encoding { get; private set; }
public string Name => "B-tree file system";
public Guid Id => new Guid("C904CF15-5222-446B-B7DB-02EAC5D781B3");
public Encoding Encoding { get; private set; }
public string Name => "B-tree file system";
public Guid Id => new Guid("C904CF15-5222-446B-B7DB-02EAC5D781B3");
public bool Identify(IMediaImage imagePlugin, Partition partition)
{
if(partition.Start >= partition.End) return false;
ulong sbSectorOff = 0x10000 / imagePlugin.Info.SectorSize;
uint sbSectorSize = 0x1000 / imagePlugin.Info.SectorSize;
ulong sbSectorOff = 0x10000 / imagePlugin.Info.SectorSize;
uint sbSectorSize = 0x1000 / imagePlugin.Info.SectorSize;
if(sbSectorOff + partition.Start >= partition.End) return false;
byte[] sector = imagePlugin.ReadSectors(sbSectorOff + partition.Start, sbSectorSize);
byte[] sector = imagePlugin.ReadSectors(sbSectorOff + partition.Start, sbSectorSize);
SuperBlock btrfsSb;
try
@@ -72,79 +72,79 @@ namespace DiscImageChef.Filesystems
}
catch { return false; }
DicConsole.DebugWriteLine("BTRFS Plugin", "sbSectorOff = {0}", sbSectorOff);
DicConsole.DebugWriteLine("BTRFS Plugin", "sbSectorSize = {0}", sbSectorSize);
DicConsole.DebugWriteLine("BTRFS Plugin", "sbSectorOff = {0}", sbSectorOff);
DicConsole.DebugWriteLine("BTRFS Plugin", "sbSectorSize = {0}", sbSectorSize);
DicConsole.DebugWriteLine("BTRFS Plugin", "partition.PartitionStartSector = {0}", partition.Start);
DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.magic = 0x{0:X16}", btrfsSb.magic);
DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.magic = 0x{0:X16}", btrfsSb.magic);
return btrfsSb.magic == BTRFS_MAGIC;
}
public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
Encoding encoding)
Encoding encoding)
{
Encoding = encoding ?? Encoding.GetEncoding("iso-8859-15");
StringBuilder sbInformation = new StringBuilder();
XmlFsType = new FileSystemType();
XmlFsType = new FileSystemType();
information = "";
ulong sbSectorOff = 0x10000 / imagePlugin.Info.SectorSize;
uint sbSectorSize = 0x1000 / imagePlugin.Info.SectorSize;
ulong sbSectorOff = 0x10000 / imagePlugin.Info.SectorSize;
uint sbSectorSize = 0x1000 / imagePlugin.Info.SectorSize;
byte[] sector = imagePlugin.ReadSectors(sbSectorOff + partition.Start, sbSectorSize);
GCHandle handle = GCHandle.Alloc(sector, GCHandleType.Pinned);
GCHandle handle = GCHandle.Alloc(sector, GCHandleType.Pinned);
SuperBlock btrfsSb = (SuperBlock)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(SuperBlock));
handle.Free();
DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.checksum = {0}", btrfsSb.checksum);
DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.uuid = {0}", btrfsSb.uuid);
DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.pba = {0}", btrfsSb.pba);
DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.flags = {0}", btrfsSb.flags);
DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.magic = {0}", btrfsSb.magic);
DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.generation = {0}", btrfsSb.generation);
DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.root_lba = {0}", btrfsSb.root_lba);
DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.chunk_lba = {0}", btrfsSb.chunk_lba);
DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.log_lba = {0}", btrfsSb.log_lba);
DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.log_root_transid = {0}", btrfsSb.log_root_transid);
DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.total_bytes = {0}", btrfsSb.total_bytes);
DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.bytes_used = {0}", btrfsSb.bytes_used);
DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.checksum = {0}", btrfsSb.checksum);
DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.uuid = {0}", btrfsSb.uuid);
DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.pba = {0}", btrfsSb.pba);
DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.flags = {0}", btrfsSb.flags);
DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.magic = {0}", btrfsSb.magic);
DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.generation = {0}", btrfsSb.generation);
DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.root_lba = {0}", btrfsSb.root_lba);
DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.chunk_lba = {0}", btrfsSb.chunk_lba);
DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.log_lba = {0}", btrfsSb.log_lba);
DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.log_root_transid = {0}", btrfsSb.log_root_transid);
DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.total_bytes = {0}", btrfsSb.total_bytes);
DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.bytes_used = {0}", btrfsSb.bytes_used);
DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.root_dir_objectid = {0}", btrfsSb.root_dir_objectid);
DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.num_devices = {0}", btrfsSb.num_devices);
DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.sectorsize = {0}", btrfsSb.sectorsize);
DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.nodesize = {0}", btrfsSb.nodesize);
DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.leafsize = {0}", btrfsSb.leafsize);
DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.stripesize = {0}", btrfsSb.stripesize);
DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.n = {0}", btrfsSb.n);
DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.num_devices = {0}", btrfsSb.num_devices);
DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.sectorsize = {0}", btrfsSb.sectorsize);
DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.nodesize = {0}", btrfsSb.nodesize);
DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.leafsize = {0}", btrfsSb.leafsize);
DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.stripesize = {0}", btrfsSb.stripesize);
DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.n = {0}", btrfsSb.n);
DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.chunk_root_generation = {0}",
btrfsSb.chunk_root_generation);
DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.compat_flags = 0x{0:X16}", btrfsSb.compat_flags);
DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.compat_flags = 0x{0:X16}", btrfsSb.compat_flags);
DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.compat_ro_flags = 0x{0:X16}", btrfsSb.compat_ro_flags);
DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.incompat_flags = 0x{0:X16}", btrfsSb.incompat_flags);
DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.csum_type = {0}", btrfsSb.csum_type);
DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.root_level = {0}", btrfsSb.root_level);
DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.chunk_root_level = {0}", btrfsSb.chunk_root_level);
DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.log_root_level = {0}", btrfsSb.log_root_level);
DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.dev_item.id = 0x{0:X16}", btrfsSb.dev_item.id);
DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.dev_item.bytes = {0}", btrfsSb.dev_item.bytes);
DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.dev_item.used = {0}", btrfsSb.dev_item.used);
DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.incompat_flags = 0x{0:X16}", btrfsSb.incompat_flags);
DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.csum_type = {0}", btrfsSb.csum_type);
DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.root_level = {0}", btrfsSb.root_level);
DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.chunk_root_level = {0}", btrfsSb.chunk_root_level);
DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.log_root_level = {0}", btrfsSb.log_root_level);
DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.dev_item.id = 0x{0:X16}", btrfsSb.dev_item.id);
DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.dev_item.bytes = {0}", btrfsSb.dev_item.bytes);
DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.dev_item.used = {0}", btrfsSb.dev_item.used);
DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.dev_item.optimal_align = {0}",
btrfsSb.dev_item.optimal_align);
DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.dev_item.optimal_width = {0}",
btrfsSb.dev_item.optimal_width);
DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.dev_item.minimal_size = {0}",
btrfsSb.dev_item.minimal_size);
DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.dev_item.type = {0}", btrfsSb.dev_item.type);
DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.dev_item.type = {0}", btrfsSb.dev_item.type);
DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.dev_item.generation = {0}", btrfsSb.dev_item.generation);
DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.dev_item.start_offset = {0}",
btrfsSb.dev_item.start_offset);
DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.dev_item.dev_group = {0}", btrfsSb.dev_item.dev_group);
DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.dev_item.dev_group = {0}", btrfsSb.dev_item.dev_group);
DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.dev_item.seek_speed = {0}", btrfsSb.dev_item.seek_speed);
DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.dev_item.bandwitdh = {0}", btrfsSb.dev_item.bandwitdh);
DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.dev_item.bandwitdh = {0}", btrfsSb.dev_item.bandwitdh);
DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.dev_item.device_uuid = {0}",
btrfsSb.dev_item.device_uuid);
DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.dev_item.uuid = {0}", btrfsSb.dev_item.uuid);
DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.label = {0}", btrfsSb.label);
DicConsole.DebugWriteLine("BTRFS Plugin", "btrfsSb.label = {0}", btrfsSb.label);
sbInformation.AppendLine("B-tree filesystem");
sbInformation.AppendFormat("UUID: {0}", btrfsSb.uuid).AppendLine();
@@ -170,13 +170,13 @@ namespace DiscImageChef.Filesystems
XmlFsType = new FileSystemType
{
Clusters = (long)(btrfsSb.total_bytes / btrfsSb.sectorsize),
ClusterSize = (int)btrfsSb.sectorsize,
Clusters = (long)(btrfsSb.total_bytes / btrfsSb.sectorsize),
ClusterSize = (int)btrfsSb.sectorsize,
FreeClustersSpecified = true,
VolumeName = btrfsSb.label,
VolumeSerial = $"{btrfsSb.uuid}",
VolumeSetIdentifier = $"{btrfsSb.dev_item.device_uuid}",
Type = Name
VolumeName = btrfsSb.label,
VolumeSerial = $"{btrfsSb.uuid}",
VolumeSetIdentifier = $"{btrfsSb.dev_item.device_uuid}",
Type = Name
};
XmlFsType.FreeClusters = XmlFsType.Clusters - (long)(btrfsSb.bytes_used / btrfsSb.sectorsize);
}
@@ -184,38 +184,43 @@ namespace DiscImageChef.Filesystems
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct SuperBlock
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x20)] public byte[] checksum;
public Guid uuid;
public ulong pba;
public ulong flags;
public ulong magic;
public ulong generation;
public ulong root_lba;
public ulong chunk_lba;
public ulong log_lba;
public ulong log_root_transid;
public ulong total_bytes;
public ulong bytes_used;
public ulong root_dir_objectid;
public ulong num_devices;
public uint sectorsize;
public uint nodesize;
public uint leafsize;
public uint stripesize;
public uint n;
public ulong chunk_root_generation;
public ulong compat_flags;
public ulong compat_ro_flags;
public ulong incompat_flags;
public ushort csum_type;
public byte root_level;
public byte chunk_root_level;
public byte log_root_level;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x20)]
public byte[] checksum;
public Guid uuid;
public ulong pba;
public ulong flags;
public ulong magic;
public ulong generation;
public ulong root_lba;
public ulong chunk_lba;
public ulong log_lba;
public ulong log_root_transid;
public ulong total_bytes;
public ulong bytes_used;
public ulong root_dir_objectid;
public ulong num_devices;
public uint sectorsize;
public uint nodesize;
public uint leafsize;
public uint stripesize;
public uint n;
public ulong chunk_root_generation;
public ulong compat_flags;
public ulong compat_ro_flags;
public ulong incompat_flags;
public ushort csum_type;
public byte root_level;
public byte chunk_root_level;
public byte log_root_level;
public DevItem dev_item;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x100)] public string label;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x100)] public byte[] reserved;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x800)] public byte[] chunkpairs;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x4D5)] public byte[] unused;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x100)]
public string label;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x100)]
public byte[] reserved;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x800)]
public byte[] chunkpairs;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x4D5)]
public byte[] unused;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
@@ -224,17 +229,17 @@ namespace DiscImageChef.Filesystems
public ulong id;
public ulong bytes;
public ulong used;
public uint optimal_align;
public uint optimal_width;
public uint minimal_size;
public uint optimal_align;
public uint optimal_width;
public uint minimal_size;
public ulong type;
public ulong generation;
public ulong start_offset;
public uint dev_group;
public byte seek_speed;
public byte bandwitdh;
public Guid device_uuid;
public Guid uuid;
public uint dev_group;
public byte seek_speed;
public byte bandwitdh;
public Guid device_uuid;
public Guid uuid;
}
}
}

View File

@@ -44,9 +44,9 @@ namespace DiscImageChef.Filesystems
public class CBM : IFilesystem
{
public FileSystemType XmlFsType { get; private set; }
public string Name => "Commodore file system";
public Guid Id => new Guid("D104744E-A376-450C-BAC0-1347C93F983B");
public Encoding Encoding { get; private set; }
public string Name => "Commodore file system";
public Guid Id => new Guid("D104744E-A376-450C-BAC0-1347C93F983B");
public Encoding Encoding { get; private set; }
public bool Identify(IMediaImage imagePlugin, Partition partition)
{
@@ -62,8 +62,8 @@ namespace DiscImageChef.Filesystems
if(imagePlugin.Info.Sectors == 3200)
{
sector = imagePlugin.ReadSector(1560);
CommodoreHeader cbmHdr = new CommodoreHeader();
IntPtr cbmHdrPtr = Marshal.AllocHGlobal(Marshal.SizeOf(cbmHdr));
CommodoreHeader cbmHdr = new CommodoreHeader();
IntPtr cbmHdrPtr = Marshal.AllocHGlobal(Marshal.SizeOf(cbmHdr));
Marshal.Copy(sector, 0, cbmHdrPtr, Marshal.SizeOf(cbmHdr));
cbmHdr = (CommodoreHeader)Marshal.PtrToStructure(cbmHdrPtr, typeof(CommodoreHeader));
Marshal.FreeHGlobal(cbmHdrPtr);
@@ -74,21 +74,21 @@ namespace DiscImageChef.Filesystems
else
{
sector = imagePlugin.ReadSector(357);
CommodoreBam cbmBam = new CommodoreBam();
IntPtr cbmBamPtr = Marshal.AllocHGlobal(Marshal.SizeOf(cbmBam));
CommodoreBam cbmBam = new CommodoreBam();
IntPtr cbmBamPtr = Marshal.AllocHGlobal(Marshal.SizeOf(cbmBam));
Marshal.Copy(sector, 0, cbmBamPtr, Marshal.SizeOf(cbmBam));
cbmBam = (CommodoreBam)Marshal.PtrToStructure(cbmBamPtr, typeof(CommodoreBam));
Marshal.FreeHGlobal(cbmBamPtr);
if(cbmBam.dosVersion == 0x41 && (cbmBam.doubleSided == 0x00 || cbmBam.doubleSided == 0x80) &&
cbmBam.unused1 == 0x00 && cbmBam.directoryTrack == 0x12) return true;
cbmBam.unused1 == 0x00 && cbmBam.directoryTrack == 0x12) return true;
}
return false;
}
public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
Encoding encoding)
Encoding encoding)
{
Encoding = new PETSCII();
byte[] sector;
@@ -99,16 +99,16 @@ namespace DiscImageChef.Filesystems
XmlFsType = new FileSystemType
{
Type = "Commodore file system",
Clusters = (long)imagePlugin.Info.Sectors,
Type = "Commodore file system",
Clusters = (long)imagePlugin.Info.Sectors,
ClusterSize = 256
};
if(imagePlugin.Info.Sectors == 3200)
{
sector = imagePlugin.ReadSector(1560);
CommodoreHeader cbmHdr = new CommodoreHeader();
IntPtr cbmHdrPtr = Marshal.AllocHGlobal(Marshal.SizeOf(cbmHdr));
CommodoreHeader cbmHdr = new CommodoreHeader();
IntPtr cbmHdrPtr = Marshal.AllocHGlobal(Marshal.SizeOf(cbmHdr));
Marshal.Copy(sector, 0, cbmHdrPtr, Marshal.SizeOf(cbmHdr));
cbmHdr = (CommodoreHeader)Marshal.PtrToStructure(cbmHdrPtr, typeof(CommodoreHeader));
Marshal.FreeHGlobal(cbmHdrPtr);
@@ -116,8 +116,8 @@ namespace DiscImageChef.Filesystems
sbInformation.AppendFormat("Directory starts at track {0} sector {1}", cbmHdr.directoryTrack,
cbmHdr.directorySector).AppendLine();
sbInformation
.AppendFormat("Disk DOS Version: {0}", Encoding.ASCII.GetString(new[] {cbmHdr.diskDosVersion}))
.AppendLine();
.AppendFormat("Disk DOS Version: {0}", Encoding.ASCII.GetString(new[] {cbmHdr.diskDosVersion}))
.AppendLine();
sbInformation.AppendFormat("DOS Version: {0}", Encoding.ASCII.GetString(new[] {cbmHdr.dosVersion}))
.AppendLine();
sbInformation.AppendFormat("Disk Version: {0}", Encoding.ASCII.GetString(new[] {cbmHdr.diskVersion}))
@@ -126,14 +126,14 @@ namespace DiscImageChef.Filesystems
sbInformation.AppendFormat("Disk name: {0}", StringHandlers.CToString(cbmHdr.name, Encoding))
.AppendLine();
XmlFsType.VolumeName = StringHandlers.CToString(cbmHdr.name, Encoding);
XmlFsType.VolumeName = StringHandlers.CToString(cbmHdr.name, Encoding);
XmlFsType.VolumeSerial = $"{cbmHdr.diskId}";
}
else
{
sector = imagePlugin.ReadSector(357);
CommodoreBam cbmBam = new CommodoreBam();
IntPtr cbmBamPtr = Marshal.AllocHGlobal(Marshal.SizeOf(cbmBam));
CommodoreBam cbmBam = new CommodoreBam();
IntPtr cbmBamPtr = Marshal.AllocHGlobal(Marshal.SizeOf(cbmBam));
Marshal.Copy(sector, 0, cbmBamPtr, Marshal.SizeOf(cbmBam));
cbmBam = (CommodoreBam)Marshal.PtrToStructure(cbmBamPtr, typeof(CommodoreBam));
Marshal.FreeHGlobal(cbmBamPtr);
@@ -149,7 +149,7 @@ namespace DiscImageChef.Filesystems
sbInformation.AppendFormat("Disk name: {0}", StringHandlers.CToString(cbmBam.name, Encoding))
.AppendLine();
XmlFsType.VolumeName = StringHandlers.CToString(cbmBam.name, Encoding);
XmlFsType.VolumeName = StringHandlers.CToString(cbmBam.name, Encoding);
XmlFsType.VolumeSerial = $"{cbmBam.diskId}";
}
@@ -178,11 +178,13 @@ namespace DiscImageChef.Filesystems
/// <summary>
/// Block allocation map
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 140)] public byte[] bam;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 140)]
public byte[] bam;
/// <summary>
/// Disk name
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public byte[] name;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[] name;
/// <summary>
/// Filled with 0xA0
/// </summary>
@@ -210,19 +212,23 @@ namespace DiscImageChef.Filesystems
/// <summary>
/// Block allocation map for Dolphin DOS extended tracks
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)] public byte[] dolphinBam;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
public byte[] dolphinBam;
/// <summary>
/// Block allocation map for Speed DOS extended tracks
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)] public byte[] speedBam;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
public byte[] speedBam;
/// <summary>
/// Unused
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 9)] public byte[] unused2;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 9)]
public byte[] unused2;
/// <summary>
/// Free sector count for second side in 1571
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 9)] public byte[] freeCount;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 9)]
public byte[] freeCount;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
@@ -247,7 +253,8 @@ namespace DiscImageChef.Filesystems
/// <summary>
/// Disk name
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public byte[] name;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[] name;
/// <summary>
/// Filled with 0xA0
/// </summary>

View File

@@ -60,7 +60,7 @@ namespace DiscImageChef.Filesystems.CPM
/// Stores all known CP/M disk definitions
/// </summary>
CpmDefinitions definitions;
IMediaImage device;
IMediaImage device;
/// <summary>
/// Cached directory listing
/// </summary>
@@ -84,7 +84,7 @@ namespace DiscImageChef.Filesystems.CPM
/// <summary>
/// Timestamp in volume label for update
/// </summary>
byte[] labelUpdateDate;
byte[] labelUpdateDate;
bool mounted;
Partition partition;
/// <summary>
@@ -118,7 +118,7 @@ namespace DiscImageChef.Filesystems.CPM
public Guid Id => new Guid("AA2B8585-41DF-4E3B-8A35-D1A935E2F8A1");
public IEnumerable<(string name, Type type, string description)> SupportedOptions =>
new(string name, Type type, string description)[] { };
new (string name, Type type, string description)[] { };
static Dictionary<string, string> GetDefaultOptions()
{

View File

@@ -78,30 +78,36 @@ namespace DiscImageChef.Filesystems.CPM
if((entry.statusUser & 0x7F) < 0x20)
{
for(int f = 0; f < 8; f++)
if(entry.filename[f] < 0x20 && entry.filename[f] != 0x00) return false;
if(entry.filename[f] < 0x20 && entry.filename[f] != 0x00)
return false;
for(int e = 0; e < 3; e++)
if(entry.extension[e] < 0x20 && entry.extension[e] != 0x00) return false;
if(entry.extension[e] < 0x20 && entry.extension[e] != 0x00)
return false;
if(!ArrayHelpers.ArrayIsNullOrWhiteSpace(entry.filename)) fileCount++;
}
else if(entry.statusUser == 0x20)
{
for(int f = 0; f < 8; f++)
if(entry.filename[f] < 0x20 && entry.filename[f] != 0x00) return false;
if(entry.filename[f] < 0x20 && entry.filename[f] != 0x00)
return false;
for(int e = 0; e < 3; e++)
if(entry.extension[e] < 0x20 && entry.extension[e] != 0x00) return false;
if(entry.extension[e] < 0x20 && entry.extension[e] != 0x00)
return false;
label = Encoding.ASCII.GetString(directory, off + 1, 11).Trim();
label = Encoding.ASCII.GetString(directory, off + 1, 11).Trim();
labelCreationDate = new byte[4];
labelUpdateDate = new byte[4];
labelUpdateDate = new byte[4];
Array.Copy(directory, off + 24, labelCreationDate, 0, 4);
Array.Copy(directory, off + 28, labelUpdateDate, 0, 4);
Array.Copy(directory, off + 28, labelUpdateDate, 0, 4);
}
else if(entry.statusUser == 0x21)
if(directory[off + 1] == 0x00) thirdPartyTimestamps = true;
else standardTimestamps |= directory[off + 21] == 0x00 && directory[off + 31] == 0x00;
if(directory[off + 1] == 0x00)
thirdPartyTimestamps = true;
else
standardTimestamps |= directory[off + 21] == 0x00 && directory[off + 31] == 0x00;
}
return fileCount > 0;

View File

@@ -112,8 +112,8 @@ namespace DiscImageChef.Filesystems.CPM
: Errno.NoSuchFile;
stat = new FileEntryInfo {Attributes = FileAttributes.Directory, BlockSize = XmlFsType.ClusterSize};
if(labelCreationDate != null) stat.CreationTime = DateHandlers.CpmToDateTime(labelCreationDate);
if(labelUpdateDate != null) stat.StatusChangeTime = DateHandlers.CpmToDateTime(labelUpdateDate);
if(labelCreationDate != null) stat.CreationTime = DateHandlers.CpmToDateTime(labelCreationDate);
if(labelUpdateDate != null) stat.StatusChangeTime = DateHandlers.CpmToDateTime(labelUpdateDate);
return Errno.NoError;
}
}

View File

@@ -159,11 +159,11 @@ namespace DiscImageChef.Filesystems.CPM
try
{
byte[] sector;
ulong sectorSize;
ulong firstDirectorySector;
ulong sectorSize;
ulong firstDirectorySector;
byte[] directory = null;
workingDefinition = null;
label = null;
label = null;
// Try Amstrad superblock
if(!cpmFound)
@@ -182,7 +182,8 @@ namespace DiscImageChef.Filesystems.CPM
// Read the superblock
IntPtr amsPtr = Marshal.AllocHGlobal(16);
Marshal.Copy(sector, amsSbOffset, amsPtr, 16);
AmstradSuperBlock amsSb = (AmstradSuperBlock)Marshal.PtrToStructure(amsPtr, typeof(AmstradSuperBlock));
AmstradSuperBlock amsSb =
(AmstradSuperBlock)Marshal.PtrToStructure(amsPtr, typeof(AmstradSuperBlock));
Marshal.FreeHGlobal(amsPtr);
// Check that format byte and sidedness indicate the same number of sizes
@@ -191,14 +192,14 @@ namespace DiscImageChef.Filesystems.CPM
amsSb.format == 2 && (amsSb.sidedness & 0x02) == 2)
{
// Calculate device limits
ulong sides = (ulong)(amsSb.format == 0 ? 1 : 2);
ulong sides = (ulong)(amsSb.format == 0 ? 1 : 2);
ulong sectorCount = (ulong)(amsSb.tps * amsSb.spt * (byte)sides);
sectorSize = (ulong)(128 << amsSb.psh);
// Compare device limits from superblock to real limits
if(sectorSize == imagePlugin.Info.SectorSize && sectorCount == imagePlugin.Info.Sectors)
{
cpmFound = true;
cpmFound = true;
firstDirectorySector = (ulong)(amsSb.off * amsSb.spt);
// Build a DiscParameterBlock
@@ -220,13 +221,14 @@ namespace DiscImageChef.Filesystems.CPM
dpb.cks = 0x10;
dpb.drm = 0x3F;
}
dpb.dsm = 0; // I don't care
dpb.exm = sectorCount == 2880 ? (byte)1 : (byte)0;
dpb.off = amsSb.off;
dpb.psh = amsSb.psh;
for(int i = 0; i < dpb.psh; i++) dpb.phm += (byte)Math.Pow(2, i);
dpb.spt = (ushort)(amsSb.spt * (sectorSize / 128));
dpb.spt = (ushort)(amsSb.spt * (sectorSize / 128));
uint directoryLength = (uint)(((ulong)dpb.drm + 1) * 32 / sectorSize);
directory = imagePlugin.ReadSectors(firstDirectorySector + partition.Start,
directoryLength);
@@ -234,23 +236,23 @@ namespace DiscImageChef.Filesystems.CPM
// Build a CP/M disk definition
workingDefinition = new CpmDefinition
{
al0 = dpb.al0,
al1 = dpb.al1,
bitrate = "LOW",
blm = dpb.blm,
bsh = dpb.bsh,
bytesPerSector = 512,
cylinders = amsSb.tps,
drm = dpb.drm,
dsm = dpb.dsm,
encoding = "MFM",
evenOdd = false,
exm = dpb.exm,
label = null,
comment = "Amstrad PCW superblock",
ofs = dpb.off,
al0 = dpb.al0,
al1 = dpb.al1,
bitrate = "LOW",
blm = dpb.blm,
bsh = dpb.bsh,
bytesPerSector = 512,
cylinders = amsSb.tps,
drm = dpb.drm,
dsm = dpb.dsm,
encoding = "MFM",
evenOdd = false,
exm = dpb.exm,
label = null,
comment = "Amstrad PCW superblock",
ofs = dpb.off,
sectorsPerTrack = amsSb.spt,
side1 = new Side {sideId = 0, sectorIds = new int[amsSb.spt]}
side1 = new Side {sideId = 0, sectorIds = new int[amsSb.spt]}
};
for(int si = 0; si < amsSb.spt; si++) workingDefinition.side1.sectorIds[si] = si + 1;
@@ -298,8 +300,8 @@ namespace DiscImageChef.Filesystems.CPM
if(sum == 0)
{
// Read the superblock
HardDiskSuperBlock hddSb = new HardDiskSuperBlock();
IntPtr hddPtr = Marshal.AllocHGlobal(Marshal.SizeOf(hddSb));
HardDiskSuperBlock hddSb = new HardDiskSuperBlock();
IntPtr hddPtr = Marshal.AllocHGlobal(Marshal.SizeOf(hddSb));
Marshal.Copy(sector, 0, hddPtr, Marshal.SizeOf(hddSb));
hddSb = (HardDiskSuperBlock)Marshal.PtrToStructure(hddPtr, typeof(HardDiskSuperBlock));
Marshal.FreeHGlobal(hddPtr);
@@ -311,10 +313,11 @@ namespace DiscImageChef.Filesystems.CPM
(ulong)((hddSb.firstCylinder * hddSb.heads + hddSb.heads) * hddSb.sectorsPerTrack);
// If volume size corresponds with working partition (this variant will be inside MBR partitioning)
if(sectorSize == imagePlugin.Info.SectorSize && startingSector == partition.Start &&
if(sectorSize == imagePlugin.Info.SectorSize &&
startingSector == partition.Start &&
sectorsInPartition + partition.Start <= partition.End)
{
cpmFound = true;
cpmFound = true;
firstDirectorySector = (ulong)(hddSb.off * hddSb.sectorsPerTrack);
// Build a DiscParameterBlock
@@ -344,27 +347,27 @@ namespace DiscImageChef.Filesystems.CPM
// Build a CP/M disk definition
workingDefinition = new CpmDefinition
{
al0 = dpb.al0,
al1 = dpb.al1,
bitrate = "HIGH",
blm = dpb.blm,
bsh = dpb.bsh,
bytesPerSector = 512,
cylinders = hddSb.cylinders,
drm = dpb.drm,
dsm = dpb.dsm,
encoding = "MFM",
evenOdd = false,
exm = dpb.exm,
label = null,
comment = "CP/M-86 hard disk superblock",
ofs = dpb.off,
al0 = dpb.al0,
al1 = dpb.al1,
bitrate = "HIGH",
blm = dpb.blm,
bsh = dpb.bsh,
bytesPerSector = 512,
cylinders = hddSb.cylinders,
drm = dpb.drm,
dsm = dpb.dsm,
encoding = "MFM",
evenOdd = false,
exm = dpb.exm,
label = null,
comment = "CP/M-86 hard disk superblock",
ofs = dpb.off,
sectorsPerTrack = hddSb.sectorsPerTrack,
side1 = new Side {sideId = 0, sectorIds = new int[hddSb.sectorsPerTrack]},
order = "SIDES",
side2 = new Side {sideId = 1, sectorIds = new int[hddSb.sectorsPerTrack]},
skew = 0,
sofs = 0
side1 = new Side {sideId = 0, sectorIds = new int[hddSb.sectorsPerTrack]},
order = "SIDES",
side2 = new Side {sideId = 1, sectorIds = new int[hddSb.sectorsPerTrack]},
skew = 0,
sofs = 0
};
for(int si = 0; si < hddSb.sectorsPerTrack; si++)
@@ -383,8 +386,10 @@ namespace DiscImageChef.Filesystems.CPM
// Check for alternate location of format ID
if(sector.Last() == 0x00 || sector.Last() == 0xFF)
if(sector[0x40] == 0x94 || sector[0x40] == 0x26) formatByte = sector[0x40];
else formatByte = sector.Last();
if(sector[0x40] == 0x94 || sector[0x40] == 0x26)
formatByte = sector[0x40];
else
formatByte = sector.Last();
else formatByte = sector.Last();
uint firstDirectorySector86 = 0;
@@ -399,7 +404,7 @@ namespace DiscImageChef.Filesystems.CPM
case FormatByte.k160:
if(imagePlugin.Info.SectorSize == 512 && imagePlugin.Info.Sectors == 320)
{
cpmFound = true;
cpmFound = true;
firstDirectorySector86 = 8;
dpb = new DiscParameterBlock
{
@@ -419,25 +424,25 @@ namespace DiscImageChef.Filesystems.CPM
workingDefinition = new CpmDefinition
{
al0 = dpb.al0,
al1 = dpb.al1,
bitrate = "LOW",
blm = dpb.blm,
bsh = dpb.bsh,
bytesPerSector = 512,
cylinders = 40,
drm = dpb.drm,
dsm = dpb.dsm,
encoding = "MFM",
evenOdd = false,
exm = dpb.exm,
label = null,
comment = "CP/M-86 floppy identifier",
ofs = dpb.off,
al0 = dpb.al0,
al1 = dpb.al1,
bitrate = "LOW",
blm = dpb.blm,
bsh = dpb.bsh,
bytesPerSector = 512,
cylinders = 40,
drm = dpb.drm,
dsm = dpb.dsm,
encoding = "MFM",
evenOdd = false,
exm = dpb.exm,
label = null,
comment = "CP/M-86 floppy identifier",
ofs = dpb.off,
sectorsPerTrack = 8,
side1 = new Side {sideId = 0, sectorIds = new int[8]},
skew = 0,
sofs = 0
side1 = new Side {sideId = 0, sectorIds = new int[8]},
skew = 0,
sofs = 0
};
for(int si = 0; si < 8; si++) workingDefinition.side1.sectorIds[si] = si + 1;
@@ -447,7 +452,7 @@ namespace DiscImageChef.Filesystems.CPM
case FormatByte.k320:
if(imagePlugin.Info.SectorSize == 512 && imagePlugin.Info.Sectors == 640)
{
cpmFound = true;
cpmFound = true;
firstDirectorySector86 = 16;
dpb = new DiscParameterBlock
{
@@ -467,27 +472,27 @@ namespace DiscImageChef.Filesystems.CPM
workingDefinition = new CpmDefinition
{
al0 = dpb.al0,
al1 = dpb.al1,
bitrate = "LOW",
blm = dpb.blm,
bsh = dpb.bsh,
bytesPerSector = 512,
cylinders = 40,
drm = dpb.drm,
dsm = dpb.dsm,
encoding = "MFM",
evenOdd = false,
exm = dpb.exm,
label = null,
comment = "CP/M-86 floppy identifier",
ofs = dpb.off,
al0 = dpb.al0,
al1 = dpb.al1,
bitrate = "LOW",
blm = dpb.blm,
bsh = dpb.bsh,
bytesPerSector = 512,
cylinders = 40,
drm = dpb.drm,
dsm = dpb.dsm,
encoding = "MFM",
evenOdd = false,
exm = dpb.exm,
label = null,
comment = "CP/M-86 floppy identifier",
ofs = dpb.off,
sectorsPerTrack = 8,
side1 = new Side {sideId = 0, sectorIds = new int[8]},
order = "SIDES",
side2 = new Side {sideId = 1, sectorIds = new int[8]},
skew = 0,
sofs = 0
side1 = new Side {sideId = 0, sectorIds = new int[8]},
order = "SIDES",
side2 = new Side {sideId = 1, sectorIds = new int[8]},
skew = 0,
sofs = 0
};
for(int si = 0; si < 8; si++) workingDefinition.side1.sectorIds[si] = si + 1;
@@ -500,7 +505,7 @@ namespace DiscImageChef.Filesystems.CPM
case FormatByte.k360Alt2:
if(imagePlugin.Info.SectorSize == 512 && imagePlugin.Info.Sectors == 720)
{
cpmFound = true;
cpmFound = true;
firstDirectorySector86 = 36;
dpb = new DiscParameterBlock
{
@@ -520,27 +525,27 @@ namespace DiscImageChef.Filesystems.CPM
workingDefinition = new CpmDefinition
{
al0 = dpb.al0,
al1 = dpb.al1,
bitrate = "LOW",
blm = dpb.blm,
bsh = dpb.bsh,
bytesPerSector = 512,
cylinders = 40,
drm = dpb.drm,
dsm = dpb.dsm,
encoding = "MFM",
evenOdd = false,
exm = dpb.exm,
label = null,
comment = "CP/M-86 floppy identifier",
ofs = dpb.off,
al0 = dpb.al0,
al1 = dpb.al1,
bitrate = "LOW",
blm = dpb.blm,
bsh = dpb.bsh,
bytesPerSector = 512,
cylinders = 40,
drm = dpb.drm,
dsm = dpb.dsm,
encoding = "MFM",
evenOdd = false,
exm = dpb.exm,
label = null,
comment = "CP/M-86 floppy identifier",
ofs = dpb.off,
sectorsPerTrack = 9,
side1 = new Side {sideId = 0, sectorIds = new int[9]},
order = "SIDES",
side2 = new Side {sideId = 1, sectorIds = new int[9]},
skew = 0,
sofs = 0
side1 = new Side {sideId = 0, sectorIds = new int[9]},
order = "SIDES",
side2 = new Side {sideId = 1, sectorIds = new int[9]},
skew = 0,
sofs = 0
};
for(int si = 0; si < 9; si++) workingDefinition.side1.sectorIds[si] = si + 1;
@@ -552,7 +557,7 @@ namespace DiscImageChef.Filesystems.CPM
case FormatByte.k720Alt:
if(imagePlugin.Info.SectorSize == 512 && imagePlugin.Info.Sectors == 1440)
{
cpmFound = true;
cpmFound = true;
firstDirectorySector86 = 36;
dpb = new DiscParameterBlock
{
@@ -572,27 +577,27 @@ namespace DiscImageChef.Filesystems.CPM
workingDefinition = new CpmDefinition
{
al0 = dpb.al0,
al1 = dpb.al1,
bitrate = "LOW",
blm = dpb.blm,
bsh = dpb.bsh,
bytesPerSector = 512,
cylinders = 80,
drm = dpb.drm,
dsm = dpb.dsm,
encoding = "MFM",
evenOdd = false,
exm = dpb.exm,
label = null,
comment = "CP/M-86 floppy identifier",
ofs = dpb.off,
al0 = dpb.al0,
al1 = dpb.al1,
bitrate = "LOW",
blm = dpb.blm,
bsh = dpb.bsh,
bytesPerSector = 512,
cylinders = 80,
drm = dpb.drm,
dsm = dpb.dsm,
encoding = "MFM",
evenOdd = false,
exm = dpb.exm,
label = null,
comment = "CP/M-86 floppy identifier",
ofs = dpb.off,
sectorsPerTrack = 9,
side1 = new Side {sideId = 0, sectorIds = new int[9]},
order = "SIDES",
side2 = new Side {sideId = 1, sectorIds = new int[9]},
skew = 0,
sofs = 0
side1 = new Side {sideId = 0, sectorIds = new int[9]},
order = "SIDES",
side2 = new Side {sideId = 1, sectorIds = new int[9]},
skew = 0,
sofs = 0
};
for(int si = 0; si < 9; si++) workingDefinition.side1.sectorIds[si] = si + 1;
@@ -603,7 +608,7 @@ namespace DiscImageChef.Filesystems.CPM
case FormatByte.f720:
if(imagePlugin.Info.SectorSize == 512 && imagePlugin.Info.Sectors == 1440)
{
cpmFound = true;
cpmFound = true;
firstDirectorySector86 = 18;
dpb = new DiscParameterBlock
{
@@ -623,27 +628,27 @@ namespace DiscImageChef.Filesystems.CPM
workingDefinition = new CpmDefinition
{
al0 = dpb.al0,
al1 = dpb.al1,
bitrate = "LOW",
blm = dpb.blm,
bsh = dpb.bsh,
bytesPerSector = 512,
cylinders = 80,
drm = dpb.drm,
dsm = dpb.dsm,
encoding = "MFM",
evenOdd = false,
exm = dpb.exm,
label = null,
comment = "CP/M-86 floppy identifier",
ofs = dpb.off,
al0 = dpb.al0,
al1 = dpb.al1,
bitrate = "LOW",
blm = dpb.blm,
bsh = dpb.bsh,
bytesPerSector = 512,
cylinders = 80,
drm = dpb.drm,
dsm = dpb.dsm,
encoding = "MFM",
evenOdd = false,
exm = dpb.exm,
label = null,
comment = "CP/M-86 floppy identifier",
ofs = dpb.off,
sectorsPerTrack = 9,
side1 = new Side {sideId = 0, sectorIds = new int[9]},
order = "CYLINDERS",
side2 = new Side {sideId = 1, sectorIds = new int[9]},
skew = 0,
sofs = 0
side1 = new Side {sideId = 0, sectorIds = new int[9]},
order = "CYLINDERS",
side2 = new Side {sideId = 1, sectorIds = new int[9]},
skew = 0,
sofs = 0
};
for(int si = 0; si < 9; si++) workingDefinition.side1.sectorIds[si] = si + 1;
@@ -654,7 +659,7 @@ namespace DiscImageChef.Filesystems.CPM
case FormatByte.f1200:
if(imagePlugin.Info.SectorSize == 512 && imagePlugin.Info.Sectors == 2400)
{
cpmFound = true;
cpmFound = true;
firstDirectorySector86 = 30;
dpb = new DiscParameterBlock
{
@@ -674,27 +679,27 @@ namespace DiscImageChef.Filesystems.CPM
workingDefinition = new CpmDefinition
{
al0 = dpb.al0,
al1 = dpb.al1,
bitrate = "HIGH",
blm = dpb.blm,
bsh = dpb.bsh,
bytesPerSector = 512,
cylinders = 80,
drm = dpb.drm,
dsm = dpb.dsm,
encoding = "MFM",
evenOdd = false,
exm = dpb.exm,
label = null,
comment = "CP/M-86 floppy identifier",
ofs = dpb.off,
al0 = dpb.al0,
al1 = dpb.al1,
bitrate = "HIGH",
blm = dpb.blm,
bsh = dpb.bsh,
bytesPerSector = 512,
cylinders = 80,
drm = dpb.drm,
dsm = dpb.dsm,
encoding = "MFM",
evenOdd = false,
exm = dpb.exm,
label = null,
comment = "CP/M-86 floppy identifier",
ofs = dpb.off,
sectorsPerTrack = 15,
side1 = new Side {sideId = 0, sectorIds = new int[15]},
order = "CYLINDERS",
side2 = new Side {sideId = 1, sectorIds = new int[15]},
skew = 0,
sofs = 0
side1 = new Side {sideId = 0, sectorIds = new int[15]},
order = "CYLINDERS",
side2 = new Side {sideId = 1, sectorIds = new int[15]},
skew = 0,
sofs = 0
};
for(int si = 0; si < 15; si++) workingDefinition.side1.sectorIds[si] = si + 1;
@@ -705,7 +710,7 @@ namespace DiscImageChef.Filesystems.CPM
case FormatByte.f1440:
if(imagePlugin.Info.SectorSize == 512 && imagePlugin.Info.Sectors == 2880)
{
cpmFound = true;
cpmFound = true;
firstDirectorySector86 = 36;
dpb = new DiscParameterBlock
{
@@ -725,27 +730,27 @@ namespace DiscImageChef.Filesystems.CPM
workingDefinition = new CpmDefinition
{
al0 = dpb.al0,
al1 = dpb.al1,
bitrate = "LOW",
blm = dpb.blm,
bsh = dpb.bsh,
bytesPerSector = 512,
cylinders = 80,
drm = dpb.drm,
dsm = dpb.dsm,
encoding = "MFM",
evenOdd = false,
exm = dpb.exm,
label = null,
comment = "CP/M-86 floppy identifier",
ofs = dpb.off,
al0 = dpb.al0,
al1 = dpb.al1,
bitrate = "LOW",
blm = dpb.blm,
bsh = dpb.bsh,
bytesPerSector = 512,
cylinders = 80,
drm = dpb.drm,
dsm = dpb.dsm,
encoding = "MFM",
evenOdd = false,
exm = dpb.exm,
label = null,
comment = "CP/M-86 floppy identifier",
ofs = dpb.off,
sectorsPerTrack = 18,
side1 = new Side {sideId = 0, sectorIds = new int[18]},
order = "CYLINDERS",
side2 = new Side {sideId = 1, sectorIds = new int[18]},
skew = 0,
sofs = 0
side1 = new Side {sideId = 0, sectorIds = new int[18]},
order = "CYLINDERS",
side2 = new Side {sideId = 1, sectorIds = new int[18]},
skew = 0,
sofs = 0
};
for(int si = 0; si < 18; si++) workingDefinition.side1.sectorIds[si] = si + 1;
@@ -786,7 +791,7 @@ namespace DiscImageChef.Filesystems.CPM
foreach(CpmDefinition def in from def in definitions.definitions
let sectors =
(ulong)(def.cylinders * def.sides * def.sectorsPerTrack)
where sectors == imagePlugin.Info.Sectors &&
where sectors == imagePlugin.Info.Sectors &&
def.bytesPerSector == imagePlugin.Info.SectorSize
select def)
{
@@ -794,7 +799,7 @@ namespace DiscImageChef.Filesystems.CPM
DicConsole.DebugWriteLine("CP/M Plugin", "Trying definition \"{0}\"", def.comment);
ulong offset;
if(def.sofs != 0) offset = (ulong)def.sofs;
else offset = (ulong)(def.ofs * def.sectorsPerTrack);
else offset = (ulong)(def.ofs * def.sectorsPerTrack);
int dirLen = (def.drm + 1) * 32 / def.bytesPerSector;
@@ -828,7 +833,8 @@ namespace DiscImageChef.Filesystems.CPM
for(int m = 0; m < def.side1.sectorIds.Length; m++)
sectorMask[m + def.side1.sectorIds.Length] =
def.side1.sectorIds[m] - def.side1.sectorIds[0] +
def.side1.sectorIds.Length + def.side2.sectorIds.Length;
def.side1.sectorIds.Length +
def.side2.sectorIds.Length;
}
// TODO: Implement COLUMBIA ordering
else if(string.Compare(def.order, "COLUMBIA",
@@ -839,9 +845,8 @@ namespace DiscImageChef.Filesystems.CPM
continue;
}
// TODO: Implement EAGLE ordering
else if(
string.Compare(def.order, "EAGLE", StringComparison.InvariantCultureIgnoreCase) == 0
)
else if(string.Compare(def.order, "EAGLE",
StringComparison.InvariantCultureIgnoreCase) == 0)
{
DicConsole.DebugWriteLine("CP/M Plugin",
"Don't know how to handle EAGLE ordering, not proceeding with this definition.");
@@ -861,7 +866,8 @@ namespace DiscImageChef.Filesystems.CPM
for(int p = 0; p < dirLen; p++)
{
byte[] dirSector =
imagePlugin.ReadSector((ulong)((int)offset + (int)partition.Start +
imagePlugin.ReadSector((ulong)((int)offset +
(int)partition.Start +
p / sectorMask.Length * sectorMask.Length +
sectorMask[p % sectorMask.Length]));
ms.Write(dirSector, 0, dirSector.Length);
@@ -875,7 +881,8 @@ namespace DiscImageChef.Filesystems.CPM
// Complement of the directory bytes if needed
if(def.complement)
for(int b = 0; b < directory.Length; b++) directory[b] = (byte)(~directory[b] & 0xFF);
for(int b = 0; b < directory.Length; b++)
directory[b] = (byte)(~directory[b] & 0xFF);
// Check the directory
if(CheckDir(directory))
@@ -939,25 +946,25 @@ namespace DiscImageChef.Filesystems.CPM
break;
}
cpmFound = true;
cpmFound = true;
workingDefinition = def;
return true;
}
label = null;
label = null;
labelCreationDate = null;
labelUpdateDate = null;
labelUpdateDate = null;
}
}
}
// Clear class variables
cpmFound = false;
workingDefinition = null;
dpb = null;
label = null;
standardTimestamps = false;
cpmFound = false;
workingDefinition = null;
dpb = null;
label = null;
standardTimestamps = false;
thirdPartyTimestamps = false;
return false;
}
@@ -969,9 +976,9 @@ namespace DiscImageChef.Filesystems.CPM
}
public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
Encoding encoding)
Encoding encoding)
{
Encoding = encoding ?? Encoding.GetEncoding("IBM437");
Encoding = encoding ?? Encoding.GetEncoding("IBM437");
information = "";
// As the identification is so complex, just call Identify() and relay on its findings
if(!Identify(imagePlugin, partition) || !cpmFound || workingDefinition == null || dpb == null) return;
@@ -1007,6 +1014,7 @@ namespace DiscImageChef.Filesystems.CPM
if(interleaveSide2 > 1)
sb.AppendFormat("Side 1 uses {0}:1 software interleaving", interleaveSide2).AppendLine();
}
switch(workingDefinition.order)
{
case "SIDES":
@@ -1044,22 +1052,24 @@ namespace DiscImageChef.Filesystems.CPM
if(labelUpdateDate != null)
sb.AppendFormat("Volume updated on {0}", DateHandlers.CpmToDateTime(labelUpdateDate)).AppendLine();
XmlFsType = new FileSystemType();
XmlFsType.Bootable |= workingDefinition.sofs > 0 || workingDefinition.ofs > 0;
XmlFsType.ClusterSize = 128 << dpb.bsh;
XmlFsType = new FileSystemType();
XmlFsType.Bootable |= workingDefinition.sofs > 0 || workingDefinition.ofs > 0;
XmlFsType.ClusterSize = 128 << dpb.bsh;
if(dpb.dsm > 0) XmlFsType.Clusters = dpb.dsm;
else XmlFsType.Clusters = (long)(partition.End - partition.Start);
else XmlFsType.Clusters = (long)(partition.End - partition.Start);
if(labelCreationDate != null)
{
XmlFsType.CreationDate = DateHandlers.CpmToDateTime(labelCreationDate);
XmlFsType.CreationDate = DateHandlers.CpmToDateTime(labelCreationDate);
XmlFsType.CreationDateSpecified = true;
}
if(labelUpdateDate != null)
{
XmlFsType.ModificationDate = DateHandlers.CpmToDateTime(labelUpdateDate);
XmlFsType.ModificationDate = DateHandlers.CpmToDateTime(labelUpdateDate);
XmlFsType.ModificationDateSpecified = true;
}
XmlFsType.Type = "CP/M";
XmlFsType.Type = "CP/M";
XmlFsType.VolumeName = label;
information = sb.ToString();

View File

@@ -176,7 +176,8 @@ namespace DiscImageChef.Filesystems.CPM
/// <summary>
/// Copyright string
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x1F)] public byte[] copyright;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x1F)]
public byte[] copyright;
/// <summary>
/// First cylinder of disk where this volume resides
/// </summary>
@@ -288,7 +289,8 @@ namespace DiscImageChef.Filesystems.CPM
/// <summary>
/// Label in ASCII
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 11)] public byte[] label;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 11)]
public byte[] label;
/// <summary>
/// Label flags. Bit 0 = label exists, bit 4 = creation timestamp, bit 5 = modification timestamp, bit 6 = access
/// timestamp, bit 7 = password enabled
@@ -305,15 +307,18 @@ namespace DiscImageChef.Filesystems.CPM
/// <summary>
/// Password XOR'ed with <see cref="passwordDecoder" />
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] public byte[] password;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public byte[] password;
/// <summary>
/// Label creation time
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] public byte[] ctime;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public byte[] ctime;
/// <summary>
/// Label modification time
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] public byte[] mtime;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public byte[] mtime;
}
/// <summary>
@@ -329,11 +334,13 @@ namespace DiscImageChef.Filesystems.CPM
/// <summary>
/// File 1 create/access timestamp
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] public byte[] date1;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public byte[] date1;
/// <summary>
/// File 1 modification timestamp
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] public byte[] date2;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public byte[] date2;
/// <summary>
/// File 1 password mode
/// </summary>
@@ -342,11 +349,13 @@ namespace DiscImageChef.Filesystems.CPM
/// <summary>
/// File 2 create/access timestamp
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] public byte[] date3;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public byte[] date3;
/// <summary>
/// File 2 modification timestamp
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] public byte[] date4;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public byte[] date4;
/// <summary>
/// File 2 password mode
/// </summary>
@@ -355,11 +364,13 @@ namespace DiscImageChef.Filesystems.CPM
/// <summary>
/// File 3 create/access timestamp
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] public byte[] date5;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public byte[] date5;
/// <summary>
/// File 3 modification timestamp
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] public byte[] date6;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public byte[] date6;
/// <summary>
/// File 3 password mode
/// </summary>
@@ -380,11 +391,13 @@ namespace DiscImageChef.Filesystems.CPM
/// <summary>
/// Filename
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] public byte[] filename;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public byte[] filename;
/// <summary>
/// Extension
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] public byte[] extension;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public byte[] extension;
/// <summary>
/// Password mode. Bit 7 = required for read, bit 6 = required for write, bit 5 = required for delete
/// </summary>
@@ -393,12 +406,15 @@ namespace DiscImageChef.Filesystems.CPM
/// Password decoder byte
/// </summary>
public byte passwordDecoder;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] public byte[] reserved;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public byte[] reserved;
/// <summary>
/// Password XOR'ed with <see cref="passwordDecoder" />
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] public byte[] password;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] public byte[] reserved2;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public byte[] password;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public byte[] reserved2;
}
/// <summary>
@@ -415,39 +431,48 @@ namespace DiscImageChef.Filesystems.CPM
/// <summary>
/// Creation year for file 1
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] public byte[] create1;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public byte[] create1;
/// <summary>
/// Modification time for file 1
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] public byte[] modify1;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public byte[] modify1;
/// <summary>
/// Access time for file 1
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] public byte[] access1;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public byte[] access1;
/// <summary>
/// Creation year for file 2
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] public byte[] create2;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public byte[] create2;
/// <summary>
/// Modification time for file 2
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] public byte[] modify2;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public byte[] modify2;
/// <summary>
/// Access time for file 2
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] public byte[] access2;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public byte[] access2;
/// <summary>
/// Creation year for file 3
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] public byte[] create3;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public byte[] create3;
/// <summary>
/// Modification time for file 3
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] public byte[] modify3;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public byte[] modify3;
/// <summary>
/// Access time for file 3
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] public byte[] access3;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public byte[] access3;
}
/// <summary>
@@ -463,11 +488,13 @@ namespace DiscImageChef.Filesystems.CPM
/// <summary>
/// Filename and bit 7 as flags
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] public byte[] filename;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public byte[] filename;
/// <summary>
/// Extension and bit 7 as flags
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] public byte[] extension;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public byte[] extension;
/// <summary>
/// Low byte of extent number
/// </summary>
@@ -489,7 +516,8 @@ namespace DiscImageChef.Filesystems.CPM
/// <summary>
/// Allocation blocks
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public byte[] allocations;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[] allocations;
}
/// <summary>
@@ -505,11 +533,13 @@ namespace DiscImageChef.Filesystems.CPM
/// <summary>
/// Filename and bit 7 as flags
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] public byte[] filename;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public byte[] filename;
/// <summary>
/// Extension and bit 7 as flags
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] public byte[] extension;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public byte[] extension;
/// <summary>
/// Low byte of extent number
/// </summary>
@@ -531,7 +561,8 @@ namespace DiscImageChef.Filesystems.CPM
/// <summary>
/// Allocation blocks
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] public ushort[] allocations;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public ushort[] allocations;
}
}
}

View File

@@ -76,7 +76,7 @@ namespace DiscImageChef.Filesystems.CPM
sectorMask[m] = workingDefinition.side1.sectorIds[m] - workingDefinition.side1.sectorIds[0];
// Skip first track (first side)
for(int m = 0; m < workingDefinition.side2.sectorIds.Length; m++)
sectorMask[m + workingDefinition.side1.sectorIds.Length] =
sectorMask[m + workingDefinition.side1.sectorIds.Length] =
workingDefinition.side2.sectorIds[m] - workingDefinition.side2.sectorIds[0] +
workingDefinition.side1.sectorIds.Length;
}
@@ -88,9 +88,10 @@ namespace DiscImageChef.Filesystems.CPM
sectorMask[m] = workingDefinition.side1.sectorIds[m] - workingDefinition.side1.sectorIds[0];
// Skip first track (first side) and first track (second side)
for(int m = 0; m < workingDefinition.side1.sectorIds.Length; m++)
sectorMask[m + workingDefinition.side1.sectorIds.Length] =
workingDefinition.side1.sectorIds[m] - workingDefinition.side1.sectorIds[0] +
workingDefinition.side1.sectorIds.Length + workingDefinition.side2.sectorIds.Length;
sectorMask[m + workingDefinition.side1.sectorIds.Length] =
workingDefinition.side1.sectorIds[m] - workingDefinition.side1.sectorIds[0] +
workingDefinition.side1.sectorIds.Length +
workingDefinition.side2.sectorIds.Length;
// TODO: Implement CYLINDERS ordering
DicConsole.DebugWriteLine("CP/M Plugin", "CYLINDERS ordering not yet implemented.");
@@ -132,7 +133,7 @@ namespace DiscImageChef.Filesystems.CPM
{
byte[] readSector =
device.ReadSector((ulong)((int)partition.Start + p / sectorMask.Length * sectorMask.Length +
sectorMask[p % sectorMask.Length]));
sectorMask[p % sectorMask.Length]));
if(workingDefinition.complement)
for(int b = 0; b < readSector.Length; b++)
readSector[b] = (byte)(~readSector[b] & 0xFF);
@@ -155,7 +156,7 @@ namespace DiscImageChef.Filesystems.CPM
deinterleavedSectors.TryGetValue(a, out byte[] sector);
// May it happen? Just in case, CP/M blocks are smaller than physical sectors
if(sector.Length > blockSize)
if(sector.Length > blockSize)
for(int i = 0; i < sector.Length / blockSize; i++)
{
byte[] tmp = new byte[blockSize];
@@ -175,14 +176,13 @@ namespace DiscImageChef.Filesystems.CPM
blockMs = new MemoryStream();
}
// CP/M blocks are same size than physical sectors
else
allocationBlocks.Add(blockNo++, sector);
else allocationBlocks.Add(blockNo++, sector);
}
DicConsole.DebugWriteLine("CP/M Plugin", "Reading directory.");
int dirOff;
int dirSectors = (dpb.drm + 1) * 32 / workingDefinition.bytesPerSector;
int dirSectors = (dpb.drm + 1) * 32 / workingDefinition.bytesPerSector;
if(workingDefinition.sofs > 0) dirOff = workingDefinition.sofs;
else dirOff = workingDefinition.ofs * workingDefinition.sectorsPerTrack;
@@ -198,15 +198,15 @@ namespace DiscImageChef.Filesystems.CPM
if(directory == null) return Errno.InvalidArgument;
int dirCnt = 0;
string file1 = null;
string file2 = null;
string file3 = null;
int dirCnt = 0;
string file1 = null;
string file2 = null;
string file3 = null;
Dictionary<string, Dictionary<int, List<ushort>>> fileExtents =
new Dictionary<string, Dictionary<int, List<ushort>>>();
statCache = new Dictionary<string, FileEntryInfo>();
cpmStat = new FileSystemInfo();
bool atime = false;
statCache = new Dictionary<string, FileEntryInfo>();
cpmStat = new FileSystemInfo();
bool atime = false;
dirList = new List<string>();
labelCreationDate = null;
labelUpdateDate = null;
@@ -218,7 +218,7 @@ namespace DiscImageChef.Filesystems.CPM
// For each directory entry
for(int dOff = 0; dOff < directory.Length; dOff += 32)
// Describes a file (does not support PDOS entries with user >= 16, because they're identical to password entries
if((directory[dOff] & 0x7F) < 0x10)
if((directory[dOff] & 0x7F) < 0x10)
if(allocationBlocks.Count > 256)
{
dirPtr = Marshal.AllocHGlobal(32);
@@ -227,7 +227,7 @@ namespace DiscImageChef.Filesystems.CPM
(DirectoryEntry16)Marshal.PtrToStructure(dirPtr, typeof(DirectoryEntry16));
Marshal.FreeHGlobal(dirPtr);
bool hidden = (entry.statusUser & 0x80) == 0x80;
bool hidden = (entry.statusUser & 0x80) == 0x80;
bool rdOnly = (entry.filename[0] & 0x80) == 0x80 || (entry.extension[0] & 0x80) == 0x80;
bool system = (entry.filename[1] & 0x80) == 0x80 || (entry.extension[2] & 0x80) == 0x80;
//bool backed = (entry.filename[3] & 0x80) == 0x80 || (entry.extension[3] & 0x80) == 0x80;
@@ -316,7 +316,7 @@ namespace DiscImageChef.Filesystems.CPM
DirectoryEntry entry = (DirectoryEntry)Marshal.PtrToStructure(dirPtr, typeof(DirectoryEntry));
Marshal.FreeHGlobal(dirPtr);
bool hidden = (entry.statusUser & 0x80) == 0x80;
bool hidden = (entry.statusUser & 0x80) == 0x80;
bool rdOnly = (entry.filename[0] & 0x80) == 0x80 || (entry.extension[0] & 0x80) == 0x80;
bool system = (entry.filename[1] & 0x80) == 0x80 || (entry.extension[2] & 0x80) == 0x80;
//bool backed = (entry.filename[3] & 0x80) == 0x80 || (entry.extension[3] & 0x80) == 0x80;
@@ -553,8 +553,8 @@ namespace DiscImageChef.Filesystems.CPM
else fInfo = new FileEntryInfo();
byte[] ctime = new byte[4];
ctime[0] = trdPartyDateEntry.create1[0];
ctime[1] = trdPartyDateEntry.create1[1];
ctime[0] = trdPartyDateEntry.create1[0];
ctime[1] = trdPartyDateEntry.create1[1];
fInfo.AccessTime = DateHandlers.CpmToDateTime(trdPartyDateEntry.access1);
fInfo.CreationTime = DateHandlers.CpmToDateTime(ctime);
@@ -569,8 +569,8 @@ namespace DiscImageChef.Filesystems.CPM
else fInfo = new FileEntryInfo();
byte[] ctime = new byte[4];
ctime[0] = trdPartyDateEntry.create2[0];
ctime[1] = trdPartyDateEntry.create2[1];
ctime[0] = trdPartyDateEntry.create2[0];
ctime[1] = trdPartyDateEntry.create2[1];
fInfo.AccessTime = DateHandlers.CpmToDateTime(trdPartyDateEntry.access2);
fInfo.CreationTime = DateHandlers.CpmToDateTime(ctime);
@@ -585,8 +585,8 @@ namespace DiscImageChef.Filesystems.CPM
else fInfo = new FileEntryInfo();
byte[] ctime = new byte[4];
ctime[0] = trdPartyDateEntry.create3[0];
ctime[1] = trdPartyDateEntry.create3[1];
ctime[0] = trdPartyDateEntry.create3[0];
ctime[1] = trdPartyDateEntry.create3[1];
fInfo.AccessTime = DateHandlers.CpmToDateTime(trdPartyDateEntry.access3);
fInfo.CreationTime = DateHandlers.CpmToDateTime(ctime);
@@ -608,7 +608,7 @@ namespace DiscImageChef.Filesystems.CPM
// this should not be a problem
DicConsole.DebugWriteLine("CP/M Plugin", "Reading files.");
long usedBlocks = 0;
fileCache = new Dictionary<string, byte[]>();
fileCache = new Dictionary<string, byte[]>();
foreach(string filename in dirList)
{
MemoryStream fileMs = new MemoryStream();

View File

@@ -54,7 +54,8 @@ namespace DiscImageChef.Filesystems.CPM
if(!fileCache.ContainsKey(pathElements[0].ToUpperInvariant())) return Errno.NoSuchFile;
if(string.Compare(xattr, "com.caldera.cpm.password", StringComparison.InvariantCulture) == 0)
if(!passwordCache.TryGetValue(pathElements[0].ToUpperInvariant(), out buf)) return Errno.NoError;
if(!passwordCache.TryGetValue(pathElements[0].ToUpperInvariant(), out buf))
return Errno.NoError;
if(string.Compare(xattr, "com.caldera.cpm.password.text", StringComparison.InvariantCulture) != 0)
return Errno.NoSuchExtendedAttribute;

View File

@@ -48,9 +48,9 @@ namespace DiscImageChef.Filesystems
const uint CRAM_CIGAM = 0x453DCD28;
public FileSystemType XmlFsType { get; private set; }
public Encoding Encoding { get; private set; }
public string Name => "Cram filesystem";
public Guid Id => new Guid("F8F6E46F-7A2A-48E3-9C0A-46AF4DC29E09");
public Encoding Encoding { get; private set; }
public string Name => "Cram filesystem";
public Guid Id => new Guid("F8F6E46F-7A2A-48E3-9C0A-46AF4DC29E09");
public bool Identify(IMediaImage imagePlugin, Partition partition)
{
@@ -64,14 +64,14 @@ namespace DiscImageChef.Filesystems
}
public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
Encoding encoding)
Encoding encoding)
{
Encoding = encoding ?? Encoding.GetEncoding("iso-8859-15");
byte[] sector = imagePlugin.ReadSector(partition.Start);
uint magic = BitConverter.ToUInt32(sector, 0x00);
uint magic = BitConverter.ToUInt32(sector, 0x00);
CramSuperBlock crSb = new CramSuperBlock();
bool littleEndian = true;
CramSuperBlock crSb = new CramSuperBlock();
bool littleEndian = true;
switch(magic)
{
@@ -82,7 +82,7 @@ namespace DiscImageChef.Filesystems
Marshal.FreeHGlobal(crSbPtr);
break;
case CRAM_CIGAM:
crSb = BigEndianMarshal.ByteArrayToStructureBigEndian<CramSuperBlock>(sector);
crSb = BigEndianMarshal.ByteArrayToStructureBigEndian<CramSuperBlock>(sector);
littleEndian = false;
break;
}
@@ -101,12 +101,12 @@ namespace DiscImageChef.Filesystems
XmlFsType = new FileSystemType
{
VolumeName = StringHandlers.CToString(crSb.name, Encoding),
Type = "Cram file system",
Clusters = crSb.blocks,
Files = crSb.files,
FilesSpecified = true,
FreeClusters = 0,
VolumeName = StringHandlers.CToString(crSb.name, Encoding),
Type = "Cram file system",
Clusters = crSb.blocks,
Files = crSb.files,
FilesSpecified = true,
FreeClusters = 0,
FreeClustersSpecified = true
};
}
@@ -115,9 +115,9 @@ namespace DiscImageChef.Filesystems
{
Zlib = 1,
Lzma = 2,
Lzo = 3,
Xz = 4,
Lz4 = 5
Lzo = 3,
Xz = 4,
Lz4 = 5
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
@@ -127,12 +127,14 @@ namespace DiscImageChef.Filesystems
public uint size;
public uint flags;
public uint future;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public byte[] signature;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[] signature;
public uint crc;
public uint edition;
public uint blocks;
public uint files;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public byte[] name;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[] name;
}
}
}

View File

@@ -44,9 +44,9 @@ namespace DiscImageChef.Filesystems
{
readonly byte[] ecma67_magic = {0x56, 0x4F, 0x4C};
public Encoding Encoding { get; private set; }
public string Name => "ECMA-67";
public Guid Id => new Guid("62A2D44A-CBC1-4377-B4B6-28C5C92034A1");
public Encoding Encoding { get; private set; }
public string Name => "ECMA-67";
public Guid Id => new Guid("62A2D44A-CBC1-4377-B4B6-28C5C92034A1");
public FileSystemType XmlFsType { get; private set; }
public bool Identify(IMediaImage imagePlugin, Partition partition)
@@ -59,8 +59,8 @@ namespace DiscImageChef.Filesystems
if(sector.Length != 128) return false;
VolumeLabel vol = new VolumeLabel();
IntPtr volPtr = Marshal.AllocHGlobal(Marshal.SizeOf(vol));
VolumeLabel vol = new VolumeLabel();
IntPtr volPtr = Marshal.AllocHGlobal(Marshal.SizeOf(vol));
Marshal.Copy(sector, 0, volPtr, Marshal.SizeOf(vol));
vol = (VolumeLabel)Marshal.PtrToStructure(volPtr, typeof(VolumeLabel));
Marshal.FreeHGlobal(volPtr);
@@ -69,15 +69,15 @@ namespace DiscImageChef.Filesystems
}
public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
Encoding encoding)
Encoding encoding)
{
Encoding = encoding ?? Encoding.GetEncoding("iso-8859-1");
byte[] sector = imagePlugin.ReadSector(6);
StringBuilder sbInformation = new StringBuilder();
VolumeLabel vol = new VolumeLabel();
IntPtr volPtr = Marshal.AllocHGlobal(Marshal.SizeOf(vol));
VolumeLabel vol = new VolumeLabel();
IntPtr volPtr = Marshal.AllocHGlobal(Marshal.SizeOf(vol));
Marshal.Copy(sector, 0, volPtr, Marshal.SizeOf(vol));
vol = (VolumeLabel)Marshal.PtrToStructure(volPtr, typeof(VolumeLabel));
Marshal.FreeHGlobal(volPtr);
@@ -89,10 +89,10 @@ namespace DiscImageChef.Filesystems
XmlFsType = new FileSystemType
{
Type = "ECMA-67",
Type = "ECMA-67",
ClusterSize = 256,
Clusters = (long)(partition.End - partition.Start + 1),
VolumeName = Encoding.ASCII.GetString(vol.volumeIdentifier)
Clusters = (long)(partition.End - partition.Start + 1),
VolumeName = Encoding.ASCII.GetString(vol.volumeIdentifier)
};
information = sbInformation.ToString();
@@ -101,20 +101,28 @@ namespace DiscImageChef.Filesystems
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct VolumeLabel
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] public byte[] labelIdentifier;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public byte[] labelIdentifier;
public byte labelNumber;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)] public byte[] volumeIdentifier;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
public byte[] volumeIdentifier;
public byte volumeAccessibility;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 26)] public byte[] reserved1;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 14)] public byte[] owner;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)] public byte[] reserved2;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 26)]
public byte[] reserved1;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 14)]
public byte[] owner;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
public byte[] reserved2;
public byte surface;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] public byte[] reserved3;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public byte[] reserved3;
public byte recordLength;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] public byte[] reserved4;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public byte[] reserved4;
public byte fileLabelAllocation;
public byte labelStandardVersion;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 48)] public byte[] reserved5;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 48)]
public byte[] reserved5;
}
}
}

View File

@@ -43,13 +43,13 @@ namespace DiscImageChef.Filesystems
{
public class EFS : IFilesystem
{
const uint EFS_MAGIC = 0x00072959;
const uint EFS_MAGIC = 0x00072959;
const uint EFS_MAGIC_NEW = 0x0007295A;
public FileSystemType XmlFsType { get; private set; }
public Encoding Encoding { get; private set; }
public string Name => "Extent File System Plugin";
public Guid Id => new Guid("52A43F90-9AF3-4391-ADFE-65598DEEABAB");
public Encoding Encoding { get; private set; }
public string Name => "Extent File System Plugin";
public Guid Id => new Guid("52A43F90-9AF3-4391-ADFE-65598DEEABAB");
public bool Identify(IMediaImage imagePlugin, Partition partition)
{
@@ -99,9 +99,9 @@ namespace DiscImageChef.Filesystems
}
public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
Encoding encoding)
Encoding encoding)
{
Encoding = encoding ?? Encoding.GetEncoding("iso-8859-15");
Encoding = encoding ?? Encoding.GetEncoding("iso-8859-15");
information = "";
if(imagePlugin.Info.SectorSize < 512) return;
@@ -160,7 +160,7 @@ namespace DiscImageChef.Filesystems
if(efsSb.sb_replsb > 0)
sb.AppendFormat("Replacement superblock resides at block {0}", efsSb.sb_replsb).AppendLine();
if(efsSb.sb_lastinode > 0) sb.AppendFormat("Last inode allocated: {0}", efsSb.sb_lastinode).AppendLine();
if(efsSb.sb_dirty > 0) sb.AppendLine("Volume is dirty");
if(efsSb.sb_dirty > 0) sb.AppendLine("Volume is dirty");
sb.AppendFormat("Checksum: 0x{0:X8}", efsSb.sb_checksum).AppendLine();
sb.AppendFormat("Volume name: {0}", StringHandlers.CToString(efsSb.sb_fname, Encoding)).AppendLine();
sb.AppendFormat("Volume pack: {0}", StringHandlers.CToString(efsSb.sb_fpack, Encoding)).AppendLine();
@@ -169,15 +169,15 @@ namespace DiscImageChef.Filesystems
XmlFsType = new FileSystemType
{
Type = "Extent File System",
ClusterSize = 512,
Clusters = efsSb.sb_size,
FreeClusters = efsSb.sb_tfree,
Type = "Extent File System",
ClusterSize = 512,
Clusters = efsSb.sb_size,
FreeClusters = efsSb.sb_tfree,
FreeClustersSpecified = true,
Dirty = efsSb.sb_dirty > 0,
VolumeName = StringHandlers.CToString(efsSb.sb_fname, Encoding),
VolumeSerial = $"{efsSb.sb_checksum:X8}",
CreationDate = DateHandlers.UnixToDateTime(efsSb.sb_time),
Dirty = efsSb.sb_dirty > 0,
VolumeName = StringHandlers.CToString(efsSb.sb_fname, Encoding),
VolumeSerial = $"{efsSb.sb_checksum:X8}",
CreationDate = DateHandlers.UnixToDateTime(efsSb.sb_time),
CreationDateSpecified = true
};
}
@@ -209,9 +209,11 @@ namespace DiscImageChef.Filesystems
/* 28: magic [0] */
public uint sb_magic;
/* 32: name of filesystem */
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)] public byte[] sb_fname;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
public byte[] sb_fname;
/* 38: name of filesystem pack */
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)] public byte[] sb_fpack;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
public byte[] sb_fpack;
/* 44: bitmap size (in bytes) */
public int sb_bmsize;
/* 48: total free data blocks */
@@ -225,7 +227,8 @@ namespace DiscImageChef.Filesystems
/* 64: last allocated inode */
public int sb_lastinode;
/* 68: unused */
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)] public byte[] sb_spare;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
public byte[] sb_spare;
/* 88: checksum (all above) */
public uint sb_checksum;
}

View File

@@ -42,23 +42,23 @@ namespace DiscImageChef.Filesystems
{
public class F2FS : IFilesystem
{
const uint F2FS_MAGIC = 0xF2F52010;
const uint F2FS_MAGIC = 0xF2F52010;
const uint F2FS_SUPER_OFFSET = 1024;
const uint F2FS_MIN_SECTOR = 512;
const uint F2FS_MAX_SECTOR = 4096;
const uint F2FS_BLOCK_SIZE = 4096;
const uint F2FS_MIN_SECTOR = 512;
const uint F2FS_MAX_SECTOR = 4096;
const uint F2FS_BLOCK_SIZE = 4096;
public FileSystemType XmlFsType { get; private set; }
public Encoding Encoding { get; private set; }
public string Name => "F2FS Plugin";
public Guid Id => new Guid("82B0920F-5F0D-4063-9F57-ADE0AE02ECE5");
public Encoding Encoding { get; private set; }
public string Name => "F2FS Plugin";
public Guid Id => new Guid("82B0920F-5F0D-4063-9F57-ADE0AE02ECE5");
public bool Identify(IMediaImage imagePlugin, Partition partition)
{
if(imagePlugin.Info.SectorSize < F2FS_MIN_SECTOR || imagePlugin.Info.SectorSize > F2FS_MAX_SECTOR)
return false;
uint sbAddr = F2FS_SUPER_OFFSET / imagePlugin.Info.SectorSize;
uint sbAddr = F2FS_SUPER_OFFSET / imagePlugin.Info.SectorSize;
if(sbAddr == 0) sbAddr = 1;
F2FS_Superblock f2fsSb = new F2FS_Superblock();
@@ -80,13 +80,13 @@ namespace DiscImageChef.Filesystems
}
public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
Encoding encoding)
Encoding encoding)
{
Encoding = Encoding.Unicode;
Encoding = Encoding.Unicode;
information = "";
if(imagePlugin.Info.SectorSize < F2FS_MIN_SECTOR || imagePlugin.Info.SectorSize > F2FS_MAX_SECTOR) return;
uint sbAddr = F2FS_SUPER_OFFSET / imagePlugin.Info.SectorSize;
uint sbAddr = F2FS_SUPER_OFFSET / imagePlugin.Info.SectorSize;
if(sbAddr == 0) sbAddr = 1;
F2FS_Superblock f2fsSb = new F2FS_Superblock();
@@ -110,7 +110,7 @@ namespace DiscImageChef.Filesystems
sb.AppendFormat("Version {0}.{1}", f2fsSb.major_ver, f2fsSb.minor_ver).AppendLine();
sb.AppendFormat("{0} bytes per sector", 1 << (int)f2fsSb.log_sectorsize).AppendLine();
sb.AppendFormat("{0} sectors ({1} bytes) per block", 1 << (int)f2fsSb.log_sectors_per_block,
1 << (int)f2fsSb.log_blocksize).AppendLine();
1 << (int)f2fsSb.log_blocksize).AppendLine();
sb.AppendFormat("{0} blocks per segment", f2fsSb.log_blocks_per_seg).AppendLine();
sb.AppendFormat("{0} blocks in volume", f2fsSb.block_count).AppendLine();
sb.AppendFormat("{0} segments per section", f2fsSb.segs_per_sec).AppendLine();
@@ -130,13 +130,13 @@ namespace DiscImageChef.Filesystems
XmlFsType = new FileSystemType
{
Type = "F2FS filesystem",
SystemIdentifier = Encoding.ASCII.GetString(f2fsSb.version),
Clusters = (long)f2fsSb.block_count,
ClusterSize = 1 << (int)f2fsSb.log_blocksize,
Type = "F2FS filesystem",
SystemIdentifier = Encoding.ASCII.GetString(f2fsSb.version),
Clusters = (long)f2fsSb.block_count,
ClusterSize = 1 << (int)f2fsSb.log_blocksize,
DataPreparerIdentifier = Encoding.ASCII.GetString(f2fsSb.init_version),
VolumeName = StringHandlers.CToString(f2fsSb.volume_name, Encoding.Unicode, true),
VolumeSerial = f2fsSb.uuid.ToString()
VolumeName = StringHandlers.CToString(f2fsSb.volume_name, Encoding.Unicode, true),
VolumeSerial = f2fsSb.uuid.ToString()
};
}
@@ -144,51 +144,64 @@ namespace DiscImageChef.Filesystems
[SuppressMessage("ReSharper", "InconsistentNaming")]
struct F2FS_Superblock
{
public uint magic;
public uint magic;
public ushort major_ver;
public ushort minor_ver;
public uint log_sectorsize;
public uint log_sectors_per_block;
public uint log_blocksize;
public uint log_blocks_per_seg;
public uint segs_per_sec;
public uint secs_per_zone;
public uint checksum_offset;
public ulong block_count;
public uint section_count;
public uint segment_count;
public uint segment_count_ckpt;
public uint segment_count_sit;
public uint segment_count_nat;
public uint segment_count_ssa;
public uint segment_count_main;
public uint segment0_blkaddr;
public uint cp_blkaddr;
public uint sit_blkaddr;
public uint nat_blkaddr;
public uint ssa_blkaddr;
public uint main_blkaddr;
public uint root_ino;
public uint node_ino;
public uint meta_ino;
public Guid uuid;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1024)] public byte[] volume_name;
public uint log_sectorsize;
public uint log_sectors_per_block;
public uint log_blocksize;
public uint log_blocks_per_seg;
public uint segs_per_sec;
public uint secs_per_zone;
public uint checksum_offset;
public ulong block_count;
public uint section_count;
public uint segment_count;
public uint segment_count_ckpt;
public uint segment_count_sit;
public uint segment_count_nat;
public uint segment_count_ssa;
public uint segment_count_main;
public uint segment0_blkaddr;
public uint cp_blkaddr;
public uint sit_blkaddr;
public uint nat_blkaddr;
public uint ssa_blkaddr;
public uint main_blkaddr;
public uint root_ino;
public uint node_ino;
public uint meta_ino;
public Guid uuid;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1024)]
public byte[] volume_name;
public uint extension_count;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)] public byte[] extension_list1;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)] public byte[] extension_list2;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)] public byte[] extension_list3;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)] public byte[] extension_list4;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)] public byte[] extension_list5;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)] public byte[] extension_list6;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)] public byte[] extension_list7;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)] public byte[] extension_list8;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
public byte[] extension_list1;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
public byte[] extension_list2;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
public byte[] extension_list3;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
public byte[] extension_list4;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
public byte[] extension_list5;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
public byte[] extension_list6;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
public byte[] extension_list7;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
public byte[] extension_list8;
public uint cp_payload;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)] public byte[] version;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)] public byte[] init_version;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)]
public byte[] version;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)]
public byte[] init_version;
public uint feature;
public byte encryption_level;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public byte[] encrypt_pw_salt;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 871)] public byte[] reserved;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[] encrypt_pw_salt;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 871)]
public byte[] reserved;
}
}
}

View File

@@ -44,9 +44,9 @@ namespace DiscImageChef.Filesystems
const uint FATX_MAGIC = 0x58544146;
public FileSystemType XmlFsType { get; private set; }
public Encoding Encoding { get; private set; }
public string Name => "FATX Filesystem Plugin";
public Guid Id => new Guid("ED27A721-4A17-4649-89FD-33633B46E228");
public Encoding Encoding { get; private set; }
public string Name => "FATX Filesystem Plugin";
public Guid Id => new Guid("ED27A721-4A17-4649-89FD-33633B46E228");
public bool Identify(IMediaImage imagePlugin, Partition partition)
{
@@ -60,9 +60,9 @@ namespace DiscImageChef.Filesystems
}
public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
Encoding encoding)
Encoding encoding)
{
Encoding = Encoding.UTF8;
Encoding = Encoding.UTF8;
information = "";
if(imagePlugin.Info.SectorSize < 512) return;
@@ -84,7 +84,7 @@ namespace DiscImageChef.Filesystems
XmlFsType = new FileSystemType
{
Type = "FATX filesystem",
Type = "FATX filesystem",
ClusterSize = (int)(fatxSb.sectorsPerCluster * imagePlugin.Info.SectorSize)
};
XmlFsType.Clusters = (long)((partition.End - partition.Start + 1) * imagePlugin.Info.SectorSize /

View File

@@ -81,9 +81,9 @@ namespace DiscImageChef.Filesystems
const uint UFS_BAD_CIGAM = 0x08049619;
public FileSystemType XmlFsType { get; private set; }
public Encoding Encoding { get; private set; }
public string Name => "BSD Fast File System (aka UNIX File System, UFS)";
public Guid Id => new Guid("CC90D342-05DB-48A8-988C-C1FE000034A3");
public Encoding Encoding { get; private set; }
public string Name => "BSD Fast File System (aka UNIX File System, UFS)";
public Guid Id => new Guid("CC90D342-05DB-48A8-988C-C1FE000034A3");
public bool Identify(IMediaImage imagePlugin, Partition partition)
{
@@ -93,59 +93,59 @@ namespace DiscImageChef.Filesystems
if(imagePlugin.Info.SectorSize == 2336 || imagePlugin.Info.SectorSize == 2352 ||
imagePlugin.Info.SectorSize == 2448) sbSizeInSectors = block_size / 2048;
else sbSizeInSectors = block_size / imagePlugin.Info.SectorSize;
else sbSizeInSectors = block_size / imagePlugin.Info.SectorSize;
ulong[] locations =
{
sb_start_floppy, sb_start_boot, sb_start_long_boot, sb_start_piggy, sb_start_att_dsdd,
8192 / imagePlugin.Info.SectorSize, 65536 / imagePlugin.Info.SectorSize,
8192 / imagePlugin.Info.SectorSize, 65536 / imagePlugin.Info.SectorSize,
262144 / imagePlugin.Info.SectorSize
};
return locations.Where(loc => partition.End > partition.Start + loc + sbSizeInSectors)
.Select(loc => imagePlugin.ReadSectors(partition.Start + loc, sbSizeInSectors))
.Select(ufsSbSectors => BitConverter.ToUInt32(ufsSbSectors, 0x055C))
.Any(magic => magic == UFS_MAGIC || magic == UFS_CIGAM || magic == UFS_MAGIC_BW ||
magic == UFS_CIGAM_BW || magic == UFS2_MAGIC || magic == UFS2_CIGAM ||
.Any(magic => magic == UFS_MAGIC || magic == UFS_CIGAM || magic == UFS_MAGIC_BW ||
magic == UFS_CIGAM_BW || magic == UFS2_MAGIC || magic == UFS2_CIGAM ||
magic == UFS_BAD_MAGIC || magic == UFS_BAD_CIGAM);
}
public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
Encoding encoding)
Encoding encoding)
{
Encoding = encoding ?? Encoding.GetEncoding("iso-8859-15");
Encoding = encoding ?? Encoding.GetEncoding("iso-8859-15");
information = "";
StringBuilder sbInformation = new StringBuilder();
uint magic = 0;
uint sb_size_in_sectors;
uint magic = 0;
uint sb_size_in_sectors;
byte[] ufs_sb_sectors;
ulong sb_offset = partition.Start;
bool fs_type_42bsd = false;
bool fs_type_43bsd = false;
bool fs_type_44bsd = false;
bool fs_type_ufs = false;
bool fs_type_ufs2 = false;
bool fs_type_sun = false;
bool fs_type_sun86 = false;
ulong sb_offset = partition.Start;
bool fs_type_42bsd = false;
bool fs_type_43bsd = false;
bool fs_type_44bsd = false;
bool fs_type_ufs = false;
bool fs_type_ufs2 = false;
bool fs_type_sun = false;
bool fs_type_sun86 = false;
if(imagePlugin.Info.SectorSize == 2336 || imagePlugin.Info.SectorSize == 2352 ||
imagePlugin.Info.SectorSize == 2448) sb_size_in_sectors = block_size / 2048;
else sb_size_in_sectors = block_size / imagePlugin.Info.SectorSize;
else sb_size_in_sectors = block_size / imagePlugin.Info.SectorSize;
ulong[] locations =
{
sb_start_floppy, sb_start_boot, sb_start_long_boot, sb_start_piggy, sb_start_att_dsdd,
8192 / imagePlugin.Info.SectorSize, 65536 / imagePlugin.Info.SectorSize,
8192 / imagePlugin.Info.SectorSize, 65536 / imagePlugin.Info.SectorSize,
262144 / imagePlugin.Info.SectorSize
};
foreach(ulong loc in locations.Where(loc => partition.End > partition.Start + loc + sb_size_in_sectors))
{
ufs_sb_sectors = imagePlugin.ReadSectors(partition.Start + loc, sb_size_in_sectors);
magic = BitConverter.ToUInt32(ufs_sb_sectors, 0x055C);
magic = BitConverter.ToUInt32(ufs_sb_sectors, 0x055C);
if(magic == UFS_MAGIC || magic == UFS_CIGAM || magic == UFS_MAGIC_BW || magic == UFS_CIGAM_BW ||
if(magic == UFS_MAGIC || magic == UFS_CIGAM || magic == UFS_MAGIC_BW || magic == UFS_CIGAM_BW ||
magic == UFS2_MAGIC || magic == UFS2_CIGAM || magic == UFS_BAD_MAGIC || magic == UFS_BAD_CIGAM)
{
sb_offset = partition.Start + loc;
@@ -210,65 +210,65 @@ namespace DiscImageChef.Filesystems
Marshal.FreeHGlobal(sbPtr);
UFSSuperBlock bs_sfu = BigEndianMarshal.ByteArrayToStructureBigEndian<UFSSuperBlock>(ufs_sb_sectors);
if(bs_sfu.fs_magic == UFS_MAGIC && ufs_sb.fs_magic == UFS_CIGAM ||
bs_sfu.fs_magic == UFS_MAGIC_BW && ufs_sb.fs_magic == UFS_CIGAM_BW ||
bs_sfu.fs_magic == UFS2_MAGIC && ufs_sb.fs_magic == UFS2_CIGAM ||
if(bs_sfu.fs_magic == UFS_MAGIC && ufs_sb.fs_magic == UFS_CIGAM ||
bs_sfu.fs_magic == UFS_MAGIC_BW && ufs_sb.fs_magic == UFS_CIGAM_BW ||
bs_sfu.fs_magic == UFS2_MAGIC && ufs_sb.fs_magic == UFS2_CIGAM ||
bs_sfu.fs_magic == UFS_BAD_MAGIC && ufs_sb.fs_magic == UFS_BAD_CIGAM)
{
ufs_sb = bs_sfu;
ufs_sb.fs_old_cstotal.cs_nbfree = Swapping.Swap(ufs_sb.fs_old_cstotal.cs_nbfree);
ufs_sb.fs_old_cstotal.cs_ndir = Swapping.Swap(ufs_sb.fs_old_cstotal.cs_ndir);
ufs_sb.fs_old_cstotal.cs_nffree = Swapping.Swap(ufs_sb.fs_old_cstotal.cs_nffree);
ufs_sb.fs_old_cstotal.cs_nifree = Swapping.Swap(ufs_sb.fs_old_cstotal.cs_nifree);
ufs_sb = bs_sfu;
ufs_sb.fs_old_cstotal.cs_nbfree = Swapping.Swap(ufs_sb.fs_old_cstotal.cs_nbfree);
ufs_sb.fs_old_cstotal.cs_ndir = Swapping.Swap(ufs_sb.fs_old_cstotal.cs_ndir);
ufs_sb.fs_old_cstotal.cs_nffree = Swapping.Swap(ufs_sb.fs_old_cstotal.cs_nffree);
ufs_sb.fs_old_cstotal.cs_nifree = Swapping.Swap(ufs_sb.fs_old_cstotal.cs_nifree);
ufs_sb.fs_cstotal.cs_numclusters = Swapping.Swap(ufs_sb.fs_cstotal.cs_numclusters);
ufs_sb.fs_cstotal.cs_nbfree = Swapping.Swap(ufs_sb.fs_cstotal.cs_nbfree);
ufs_sb.fs_cstotal.cs_ndir = Swapping.Swap(ufs_sb.fs_cstotal.cs_ndir);
ufs_sb.fs_cstotal.cs_nffree = Swapping.Swap(ufs_sb.fs_cstotal.cs_nffree);
ufs_sb.fs_cstotal.cs_nifree = Swapping.Swap(ufs_sb.fs_cstotal.cs_nifree);
ufs_sb.fs_cstotal.cs_spare[0] = Swapping.Swap(ufs_sb.fs_cstotal.cs_spare[0]);
ufs_sb.fs_cstotal.cs_spare[1] = Swapping.Swap(ufs_sb.fs_cstotal.cs_spare[1]);
ufs_sb.fs_cstotal.cs_spare[2] = Swapping.Swap(ufs_sb.fs_cstotal.cs_spare[2]);
ufs_sb.fs_cstotal.cs_nbfree = Swapping.Swap(ufs_sb.fs_cstotal.cs_nbfree);
ufs_sb.fs_cstotal.cs_ndir = Swapping.Swap(ufs_sb.fs_cstotal.cs_ndir);
ufs_sb.fs_cstotal.cs_nffree = Swapping.Swap(ufs_sb.fs_cstotal.cs_nffree);
ufs_sb.fs_cstotal.cs_nifree = Swapping.Swap(ufs_sb.fs_cstotal.cs_nifree);
ufs_sb.fs_cstotal.cs_spare[0] = Swapping.Swap(ufs_sb.fs_cstotal.cs_spare[0]);
ufs_sb.fs_cstotal.cs_spare[1] = Swapping.Swap(ufs_sb.fs_cstotal.cs_spare[1]);
ufs_sb.fs_cstotal.cs_spare[2] = Swapping.Swap(ufs_sb.fs_cstotal.cs_spare[2]);
}
DicConsole.DebugWriteLine("FFS plugin", "ufs_sb offset: 0x{0:X8}", sb_offset);
DicConsole.DebugWriteLine("FFS plugin", "fs_rlink: 0x{0:X8}", ufs_sb.fs_rlink);
DicConsole.DebugWriteLine("FFS plugin", "fs_sblkno: 0x{0:X8}", ufs_sb.fs_sblkno);
DicConsole.DebugWriteLine("FFS plugin", "fs_cblkno: 0x{0:X8}", ufs_sb.fs_cblkno);
DicConsole.DebugWriteLine("FFS plugin", "fs_iblkno: 0x{0:X8}", ufs_sb.fs_iblkno);
DicConsole.DebugWriteLine("FFS plugin", "fs_dblkno: 0x{0:X8}", ufs_sb.fs_dblkno);
DicConsole.DebugWriteLine("FFS plugin", "fs_size: 0x{0:X8}", ufs_sb.fs_size);
DicConsole.DebugWriteLine("FFS plugin", "fs_dsize: 0x{0:X8}", ufs_sb.fs_dsize);
DicConsole.DebugWriteLine("FFS plugin", "fs_ncg: 0x{0:X8}", ufs_sb.fs_ncg);
DicConsole.DebugWriteLine("FFS plugin", "fs_bsize: 0x{0:X8}", ufs_sb.fs_bsize);
DicConsole.DebugWriteLine("FFS plugin", "fs_fsize: 0x{0:X8}", ufs_sb.fs_fsize);
DicConsole.DebugWriteLine("FFS plugin", "fs_frag: 0x{0:X8}", ufs_sb.fs_frag);
DicConsole.DebugWriteLine("FFS plugin", "fs_minfree: 0x{0:X8}", ufs_sb.fs_minfree);
DicConsole.DebugWriteLine("FFS plugin", "fs_bmask: 0x{0:X8}", ufs_sb.fs_bmask);
DicConsole.DebugWriteLine("FFS plugin", "fs_fmask: 0x{0:X8}", ufs_sb.fs_fmask);
DicConsole.DebugWriteLine("FFS plugin", "fs_bshift: 0x{0:X8}", ufs_sb.fs_bshift);
DicConsole.DebugWriteLine("FFS plugin", "fs_fshift: 0x{0:X8}", ufs_sb.fs_fshift);
DicConsole.DebugWriteLine("FFS plugin", "fs_maxcontig: 0x{0:X8}", ufs_sb.fs_maxcontig);
DicConsole.DebugWriteLine("FFS plugin", "fs_maxbpg: 0x{0:X8}", ufs_sb.fs_maxbpg);
DicConsole.DebugWriteLine("FFS plugin", "fs_fragshift: 0x{0:X8}", ufs_sb.fs_fragshift);
DicConsole.DebugWriteLine("FFS plugin", "fs_fsbtodb: 0x{0:X8}", ufs_sb.fs_fsbtodb);
DicConsole.DebugWriteLine("FFS plugin", "fs_sbsize: 0x{0:X8}", ufs_sb.fs_sbsize);
DicConsole.DebugWriteLine("FFS plugin", "fs_csmask: 0x{0:X8}", ufs_sb.fs_csmask);
DicConsole.DebugWriteLine("FFS plugin", "fs_csshift: 0x{0:X8}", ufs_sb.fs_csshift);
DicConsole.DebugWriteLine("FFS plugin", "fs_nindir: 0x{0:X8}", ufs_sb.fs_nindir);
DicConsole.DebugWriteLine("FFS plugin", "fs_inopb: 0x{0:X8}", ufs_sb.fs_inopb);
DicConsole.DebugWriteLine("FFS plugin", "fs_optim: 0x{0:X8}", ufs_sb.fs_optim);
DicConsole.DebugWriteLine("FFS plugin", "fs_id_1: 0x{0:X8}", ufs_sb.fs_id_1);
DicConsole.DebugWriteLine("FFS plugin", "fs_id_2: 0x{0:X8}", ufs_sb.fs_id_2);
DicConsole.DebugWriteLine("FFS plugin", "fs_csaddr: 0x{0:X8}", ufs_sb.fs_csaddr);
DicConsole.DebugWriteLine("FFS plugin", "fs_cssize: 0x{0:X8}", ufs_sb.fs_cssize);
DicConsole.DebugWriteLine("FFS plugin", "fs_cgsize: 0x{0:X8}", ufs_sb.fs_cgsize);
DicConsole.DebugWriteLine("FFS plugin", "fs_ipg: 0x{0:X8}", ufs_sb.fs_ipg);
DicConsole.DebugWriteLine("FFS plugin", "fs_fpg: 0x{0:X8}", ufs_sb.fs_fpg);
DicConsole.DebugWriteLine("FFS plugin", "fs_fmod: 0x{0:X2}", ufs_sb.fs_fmod);
DicConsole.DebugWriteLine("FFS plugin", "fs_clean: 0x{0:X2}", ufs_sb.fs_clean);
DicConsole.DebugWriteLine("FFS plugin", "fs_ronly: 0x{0:X2}", ufs_sb.fs_ronly);
DicConsole.DebugWriteLine("FFS plugin", "fs_flags: 0x{0:X2}", ufs_sb.fs_flags);
DicConsole.DebugWriteLine("FFS plugin", "fs_magic: 0x{0:X8}", ufs_sb.fs_magic);
DicConsole.DebugWriteLine("FFS plugin", "fs_rlink: 0x{0:X8}", ufs_sb.fs_rlink);
DicConsole.DebugWriteLine("FFS plugin", "fs_sblkno: 0x{0:X8}", ufs_sb.fs_sblkno);
DicConsole.DebugWriteLine("FFS plugin", "fs_cblkno: 0x{0:X8}", ufs_sb.fs_cblkno);
DicConsole.DebugWriteLine("FFS plugin", "fs_iblkno: 0x{0:X8}", ufs_sb.fs_iblkno);
DicConsole.DebugWriteLine("FFS plugin", "fs_dblkno: 0x{0:X8}", ufs_sb.fs_dblkno);
DicConsole.DebugWriteLine("FFS plugin", "fs_size: 0x{0:X8}", ufs_sb.fs_size);
DicConsole.DebugWriteLine("FFS plugin", "fs_dsize: 0x{0:X8}", ufs_sb.fs_dsize);
DicConsole.DebugWriteLine("FFS plugin", "fs_ncg: 0x{0:X8}", ufs_sb.fs_ncg);
DicConsole.DebugWriteLine("FFS plugin", "fs_bsize: 0x{0:X8}", ufs_sb.fs_bsize);
DicConsole.DebugWriteLine("FFS plugin", "fs_fsize: 0x{0:X8}", ufs_sb.fs_fsize);
DicConsole.DebugWriteLine("FFS plugin", "fs_frag: 0x{0:X8}", ufs_sb.fs_frag);
DicConsole.DebugWriteLine("FFS plugin", "fs_minfree: 0x{0:X8}", ufs_sb.fs_minfree);
DicConsole.DebugWriteLine("FFS plugin", "fs_bmask: 0x{0:X8}", ufs_sb.fs_bmask);
DicConsole.DebugWriteLine("FFS plugin", "fs_fmask: 0x{0:X8}", ufs_sb.fs_fmask);
DicConsole.DebugWriteLine("FFS plugin", "fs_bshift: 0x{0:X8}", ufs_sb.fs_bshift);
DicConsole.DebugWriteLine("FFS plugin", "fs_fshift: 0x{0:X8}", ufs_sb.fs_fshift);
DicConsole.DebugWriteLine("FFS plugin", "fs_maxcontig: 0x{0:X8}", ufs_sb.fs_maxcontig);
DicConsole.DebugWriteLine("FFS plugin", "fs_maxbpg: 0x{0:X8}", ufs_sb.fs_maxbpg);
DicConsole.DebugWriteLine("FFS plugin", "fs_fragshift: 0x{0:X8}", ufs_sb.fs_fragshift);
DicConsole.DebugWriteLine("FFS plugin", "fs_fsbtodb: 0x{0:X8}", ufs_sb.fs_fsbtodb);
DicConsole.DebugWriteLine("FFS plugin", "fs_sbsize: 0x{0:X8}", ufs_sb.fs_sbsize);
DicConsole.DebugWriteLine("FFS plugin", "fs_csmask: 0x{0:X8}", ufs_sb.fs_csmask);
DicConsole.DebugWriteLine("FFS plugin", "fs_csshift: 0x{0:X8}", ufs_sb.fs_csshift);
DicConsole.DebugWriteLine("FFS plugin", "fs_nindir: 0x{0:X8}", ufs_sb.fs_nindir);
DicConsole.DebugWriteLine("FFS plugin", "fs_inopb: 0x{0:X8}", ufs_sb.fs_inopb);
DicConsole.DebugWriteLine("FFS plugin", "fs_optim: 0x{0:X8}", ufs_sb.fs_optim);
DicConsole.DebugWriteLine("FFS plugin", "fs_id_1: 0x{0:X8}", ufs_sb.fs_id_1);
DicConsole.DebugWriteLine("FFS plugin", "fs_id_2: 0x{0:X8}", ufs_sb.fs_id_2);
DicConsole.DebugWriteLine("FFS plugin", "fs_csaddr: 0x{0:X8}", ufs_sb.fs_csaddr);
DicConsole.DebugWriteLine("FFS plugin", "fs_cssize: 0x{0:X8}", ufs_sb.fs_cssize);
DicConsole.DebugWriteLine("FFS plugin", "fs_cgsize: 0x{0:X8}", ufs_sb.fs_cgsize);
DicConsole.DebugWriteLine("FFS plugin", "fs_ipg: 0x{0:X8}", ufs_sb.fs_ipg);
DicConsole.DebugWriteLine("FFS plugin", "fs_fpg: 0x{0:X8}", ufs_sb.fs_fpg);
DicConsole.DebugWriteLine("FFS plugin", "fs_fmod: 0x{0:X2}", ufs_sb.fs_fmod);
DicConsole.DebugWriteLine("FFS plugin", "fs_clean: 0x{0:X2}", ufs_sb.fs_clean);
DicConsole.DebugWriteLine("FFS plugin", "fs_ronly: 0x{0:X2}", ufs_sb.fs_ronly);
DicConsole.DebugWriteLine("FFS plugin", "fs_flags: 0x{0:X2}", ufs_sb.fs_flags);
DicConsole.DebugWriteLine("FFS plugin", "fs_magic: 0x{0:X8}", ufs_sb.fs_magic);
if(ufs_sb.fs_magic == UFS2_MAGIC) fs_type_ufs2 = true;
else
@@ -286,30 +286,30 @@ namespace DiscImageChef.Filesystems
fs_type_43bsd = false;
}
if((ufs_sb.fs_maxfilesize & 0xFFFFFFFF) > SunOSEpoch &&
if((ufs_sb.fs_maxfilesize & 0xFFFFFFFF) > SunOSEpoch &&
DateHandlers.UnixUnsignedToDateTime(ufs_sb.fs_maxfilesize & 0xFFFFFFFF) < DateTime.Now)
{
fs_type_42bsd = false;
fs_type_sun = true;
fs_type_sun = true;
fs_type_43bsd = false;
}
// This is for sure, as it is shared with a sectors/track with non-x86 SunOS, Epoch is absurdly high for that
if(ufs_sb.fs_old_npsect > SunOSEpoch && DateHandlers.UnixToDateTime(ufs_sb.fs_old_npsect) < DateTime.Now
)
if(ufs_sb.fs_old_npsect > SunOSEpoch &&
DateHandlers.UnixToDateTime(ufs_sb.fs_old_npsect) < DateTime.Now)
{
fs_type_42bsd = false;
fs_type_sun86 = true;
fs_type_sun = false;
fs_type_sun = false;
fs_type_43bsd = false;
}
if(ufs_sb.fs_cgrotor > 0x00000000 && (uint)ufs_sb.fs_cgrotor < 0xFFFFFFFF)
{
fs_type_42bsd = false;
fs_type_sun = false;
fs_type_sun = false;
fs_type_sun86 = false;
fs_type_ufs = true;
fs_type_ufs = true;
fs_type_43bsd = false;
}
@@ -324,7 +324,7 @@ namespace DiscImageChef.Filesystems
{
sbInformation.AppendLine("There are a lot of variants of UFS using overlapped values on same fields");
sbInformation
.AppendLine("I will try to guess which one it is, but unless it's UFS2, I may be surely wrong");
.AppendLine("I will try to guess which one it is, but unless it's UFS2, I may be surely wrong");
}
if(fs_type_42bsd) sbInformation.AppendLine("Guessed as 42BSD FFS");
@@ -343,11 +343,11 @@ namespace DiscImageChef.Filesystems
sbInformation.AppendFormat("Cylinder group offset in cylinder: {0}", ufs_sb.fs_old_cgoffset).AppendLine();
sbInformation.AppendFormat("Volume last written on {0}", DateHandlers.UnixToDateTime(ufs_sb.fs_old_time))
.AppendLine();
XmlFsType.ModificationDate = DateHandlers.UnixToDateTime(ufs_sb.fs_old_time);
XmlFsType.ModificationDate = DateHandlers.UnixToDateTime(ufs_sb.fs_old_time);
XmlFsType.ModificationDateSpecified = true;
sbInformation.AppendFormat("{0} blocks in volume ({1} bytes)", ufs_sb.fs_old_size,
(long)ufs_sb.fs_old_size * ufs_sb.fs_fsize).AppendLine();
XmlFsType.Clusters = ufs_sb.fs_old_size;
XmlFsType.Clusters = ufs_sb.fs_old_size;
XmlFsType.ClusterSize = ufs_sb.fs_fsize;
sbInformation.AppendFormat("{0} data blocks in volume ({1} bytes)", ufs_sb.fs_old_dsize,
(long)ufs_sb.fs_old_dsize * ufs_sb.fs_fsize).AppendLine();
@@ -395,6 +395,7 @@ namespace DiscImageChef.Filesystems
sbInformation.AppendFormat("{0} µsec for head switch", ufs_sb.fs_id_1).AppendLine();
sbInformation.AppendFormat("{0} µsec for track-to-track seek", ufs_sb.fs_id_2).AppendLine();
}
sbInformation.AppendFormat("Cylinder group summary LBA: {0}", ufs_sb.fs_old_csaddr).AppendLine();
sbInformation.AppendFormat("{0} bytes in cylinder group summary", ufs_sb.fs_cssize).AppendLine();
sbInformation.AppendFormat("{0} bytes in cylinder group", ufs_sb.fs_cgsize).AppendLine();
@@ -408,7 +409,7 @@ namespace DiscImageChef.Filesystems
sbInformation.AppendFormat("{0} directories", ufs_sb.fs_old_cstotal.cs_ndir).AppendLine();
sbInformation.AppendFormat("{0} free blocks ({1} bytes)", ufs_sb.fs_old_cstotal.cs_nbfree,
(long)ufs_sb.fs_old_cstotal.cs_nbfree * ufs_sb.fs_fsize).AppendLine();
XmlFsType.FreeClusters = ufs_sb.fs_old_cstotal.cs_nbfree;
XmlFsType.FreeClusters = ufs_sb.fs_old_cstotal.cs_nbfree;
XmlFsType.FreeClustersSpecified = true;
sbInformation.AppendFormat("{0} free inodes", ufs_sb.fs_old_cstotal.cs_nifree).AppendLine();
sbInformation.AppendFormat("{0} free frags", ufs_sb.fs_old_cstotal.cs_nffree).AppendLine();
@@ -417,6 +418,7 @@ namespace DiscImageChef.Filesystems
sbInformation.AppendLine("Superblock is under modification");
XmlFsType.Dirty = true;
}
if(ufs_sb.fs_clean == 1) sbInformation.AppendLine("Volume is clean");
if(ufs_sb.fs_ronly == 1) sbInformation.AppendLine("Volume is read-only");
sbInformation.AppendFormat("Volume flags: 0x{0:X2}", ufs_sb.fs_flags).AppendLine();
@@ -438,25 +440,26 @@ namespace DiscImageChef.Filesystems
sbInformation.AppendFormat("{0} directories", ufs_sb.fs_cstotal.cs_ndir).AppendLine();
sbInformation.AppendFormat("{0} free blocks ({1} bytes)", ufs_sb.fs_cstotal.cs_nbfree,
ufs_sb.fs_cstotal.cs_nbfree * ufs_sb.fs_fsize).AppendLine();
XmlFsType.FreeClusters = ufs_sb.fs_cstotal.cs_nbfree;
XmlFsType.FreeClusters = ufs_sb.fs_cstotal.cs_nbfree;
XmlFsType.FreeClustersSpecified = true;
sbInformation.AppendFormat("{0} free inodes", ufs_sb.fs_cstotal.cs_nifree).AppendLine();
sbInformation.AppendFormat("{0} free frags", ufs_sb.fs_cstotal.cs_nffree).AppendLine();
sbInformation.AppendFormat("{0} free clusters", ufs_sb.fs_cstotal.cs_numclusters).AppendLine();
sbInformation.AppendFormat("Volume last written on {0}", DateHandlers.UnixToDateTime(ufs_sb.fs_time))
.AppendLine();
XmlFsType.ModificationDate = DateHandlers.UnixToDateTime(ufs_sb.fs_time);
XmlFsType.ModificationDate = DateHandlers.UnixToDateTime(ufs_sb.fs_time);
XmlFsType.ModificationDateSpecified = true;
sbInformation.AppendFormat("{0} blocks ({1} bytes)", ufs_sb.fs_size, ufs_sb.fs_size * ufs_sb.fs_fsize)
.AppendLine();
XmlFsType.Clusters = ufs_sb.fs_size;
sbInformation
.AppendFormat("{0} data blocks ({1} bytes)", ufs_sb.fs_dsize, ufs_sb.fs_dsize * ufs_sb.fs_fsize)
.AppendLine();
.AppendFormat("{0} data blocks ({1} bytes)", ufs_sb.fs_dsize, ufs_sb.fs_dsize * ufs_sb.fs_fsize)
.AppendLine();
sbInformation.AppendFormat("Cylinder group summary area LBA: {0}", ufs_sb.fs_csaddr).AppendLine();
sbInformation.AppendFormat("{0} blocks pending of being freed", ufs_sb.fs_pendingblocks).AppendLine();
sbInformation.AppendFormat("{0} inodes pending of being freed", ufs_sb.fs_pendinginodes).AppendLine();
}
if(fs_type_sun)
sbInformation.AppendFormat("Volume state on {0}", DateHandlers.UnixToDateTime(ufs_sb.fs_old_npsect))
.AppendLine();
@@ -470,6 +473,7 @@ namespace DiscImageChef.Filesystems
sbInformation.AppendFormat("Volume state on {0}", DateHandlers.UnixToDateTime(ufs_sb.fs_state))
.AppendLine();
}
if(ufs_sb.fs_old_nrpos > 0)
sbInformation.AppendFormat("{0} rotational positions", ufs_sb.fs_old_nrpos).AppendLine();
if(ufs_sb.fs_old_rotbloff > 0)
@@ -505,7 +509,8 @@ namespace DiscImageChef.Filesystems
/// <summary>number of free clusters</summary>
public long cs_numclusters;
/// <summary>future expansion</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] public long[] cs_spare;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public long[] cs_spare;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
@@ -644,9 +649,11 @@ namespace DiscImageChef.Filesystems
/// <summary>old FS_ flags</summary>
public sbyte fs_old_flags;
/// <summary>name mounted on</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 468)] public byte[] fs_fsmnt;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 468)]
public byte[] fs_fsmnt;
/// <summary>volume name</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] public byte[] fs_volname;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public byte[] fs_volname;
/// <summary>system-wide uid</summary>
public ulong fs_swuid;
/// <summary>due to alignment of fs_swuid</summary>
@@ -655,7 +662,8 @@ namespace DiscImageChef.Filesystems
/// <summary>last cg searched</summary>
public int fs_cgrotor;
/// <summary>padding; was list of fs_cs buffers</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 28)] public uint[] fs_ocsp;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 28)]
public uint[] fs_ocsp;
/// <summary>(u) # of contig. allocated dirs</summary>
public uint fs_contigdirs;
/// <summary>(u) cg summary info buffer</summary>
@@ -675,7 +683,8 @@ namespace DiscImageChef.Filesystems
/// <summary>size of area reserved for metadata</summary>
public long fs_metaspace;
/// <summary>old rotation block list head</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 14)] public long[] fs_sparecon64;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 14)]
public long[] fs_sparecon64;
/// <summary>byte offset of standard superblock</summary>
public long fs_sblockloc;
/// <summary>(u) cylinder summary information</summary>
@@ -693,7 +702,8 @@ namespace DiscImageChef.Filesystems
/// <summary>(u) inodes being freed</summary>
public uint fs_pendinginodes;
/// <summary>list of snapshot inode numbers</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)] public uint[] fs_snapinum;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
public uint[] fs_snapinum;
/// <summary>expected average file size</summary>
public uint fs_avgfilesize;
/// <summary>expected # of files per directory</summary>
@@ -705,7 +715,8 @@ namespace DiscImageChef.Filesystems
/// <summary>SUJ free list</summary>
public int fs_sujfree;
/// <summary>reserved for future constants</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 23)] public int[] fs_sparecon32;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 23)]
public int[] fs_sparecon32;
/// <summary>see FS_ flags below</summary>
public int fs_flags;
/// <summary>size of cluster summary array</summary>
@@ -733,7 +744,8 @@ namespace DiscImageChef.Filesystems
/// <summary>magic number</summary>
public uint fs_magic;
/// <summary>list of blocks for each rotation</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] public byte[] fs_rotbl;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
public byte[] fs_rotbl;
}
}
}

View File

@@ -43,14 +43,14 @@ namespace DiscImageChef.Filesystems
public class Fossil : IFilesystem
{
const uint FOSSIL_HDR_MAGIC = 0x3776AE89;
const uint FOSSIL_SB_MAGIC = 0x2340A3B1;
const uint FOSSIL_SB_MAGIC = 0x2340A3B1;
// Fossil header starts at 128KiB
const ulong HEADER_POS = 128 * 1024;
public FileSystemType XmlFsType { get; private set; }
public Encoding Encoding { get; private set; }
public string Name => "Fossil Filesystem Plugin";
public Guid Id => new Guid("932BF104-43F6-494F-973C-45EF58A51DA9");
public Encoding Encoding { get; private set; }
public string Name => "Fossil Filesystem Plugin";
public Guid Id => new Guid("932BF104-43F6-494F-973C-45EF58A51DA9");
public bool Identify(IMediaImage imagePlugin, Partition partition)
{
@@ -58,8 +58,8 @@ namespace DiscImageChef.Filesystems
if(partition.Start + hdrSector > imagePlugin.Info.Sectors) return false;
byte[] sector = imagePlugin.ReadSector(partition.Start + hdrSector);
FossilHeader hdr = BigEndianMarshal.ByteArrayToStructureBigEndian<FossilHeader>(sector);
byte[] sector = imagePlugin.ReadSector(partition.Start + hdrSector);
FossilHeader hdr = BigEndianMarshal.ByteArrayToStructureBigEndian<FossilHeader>(sector);
DicConsole.DebugWriteLine("Fossil plugin", "magic at 0x{0:X8} (expected 0x{1:X8})", hdr.magic,
FOSSIL_HDR_MAGIC);
@@ -68,17 +68,17 @@ namespace DiscImageChef.Filesystems
}
public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
Encoding encoding)
Encoding encoding)
{
// Technically everything on Plan 9 from Bell Labs is in UTF-8
Encoding = Encoding.UTF8;
Encoding = Encoding.UTF8;
information = "";
if(imagePlugin.Info.SectorSize < 512) return;
ulong hdrSector = HEADER_POS / imagePlugin.Info.SectorSize;
byte[] sector = imagePlugin.ReadSector(partition.Start + hdrSector);
FossilHeader hdr = BigEndianMarshal.ByteArrayToStructureBigEndian<FossilHeader>(sector);
byte[] sector = imagePlugin.ReadSector(partition.Start + hdrSector);
FossilHeader hdr = BigEndianMarshal.ByteArrayToStructureBigEndian<FossilHeader>(sector);
DicConsole.DebugWriteLine("Fossil plugin", "magic at 0x{0:X8} (expected 0x{1:X8})", hdr.magic,
FOSSIL_HDR_MAGIC);
@@ -97,9 +97,9 @@ namespace DiscImageChef.Filesystems
XmlFsType = new FileSystemType
{
Type = "Fossil filesystem",
Type = "Fossil filesystem",
ClusterSize = hdr.blockSize,
Clusters = hdr.end
Clusters = hdr.end
};
if(sbLocation <= partition.End)
@@ -197,11 +197,13 @@ namespace DiscImageChef.Filesystems
/// <summary>
/// Venti score of last successful archive
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)] public byte[] last;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
public byte[] last;
/// <summary>
/// name of file system(just a comment)
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)] public byte[] name;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public byte[] name;
}
}
}

View File

@@ -47,15 +47,15 @@ namespace DiscImageChef.Filesystems
{
public class HAMMER : IFilesystem
{
const ulong HAMMER_FSBUF_VOLUME = 0xC8414D4DC5523031;
const ulong HAMMER_FSBUF_VOLUME = 0xC8414D4DC5523031;
const ulong HAMMER_FSBUF_VOLUME_REV = 0x313052C54D4D41C8;
const uint HAMMER_VOLHDR_SIZE = 1928;
const int HAMMER_BIGBLOCK_SIZE = 8192 * 1024;
const uint HAMMER_VOLHDR_SIZE = 1928;
const int HAMMER_BIGBLOCK_SIZE = 8192 * 1024;
public FileSystemType XmlFsType { get; private set; }
public Encoding Encoding { get; private set; }
public string Name => "HAMMER Filesystem";
public Guid Id => new Guid("91A188BF-5FD7-4677-BBD3-F59EBA9C864D");
public Encoding Encoding { get; private set; }
public string Name => "HAMMER Filesystem";
public Guid Id => new Guid("91A188BF-5FD7-4677-BBD3-F59EBA9C864D");
public bool Identify(IMediaImage imagePlugin, Partition partition)
{
@@ -73,9 +73,9 @@ namespace DiscImageChef.Filesystems
}
public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
Encoding encoding)
Encoding encoding)
{
Encoding = encoding ?? Encoding.GetEncoding("iso-8859-15");
Encoding = encoding ?? Encoding.GetEncoding("iso-8859-15");
information = "";
StringBuilder sb = new StringBuilder();
@@ -114,11 +114,11 @@ namespace DiscImageChef.Filesystems
XmlFsType = new FileSystemType
{
Clusters = (long)(partition.Size / HAMMER_BIGBLOCK_SIZE),
ClusterSize = HAMMER_BIGBLOCK_SIZE,
Dirty = false,
Type = "HAMMER",
VolumeName = StringHandlers.CToString(hammerSb.vol_label, Encoding),
Clusters = (long)(partition.Size / HAMMER_BIGBLOCK_SIZE),
ClusterSize = HAMMER_BIGBLOCK_SIZE,
Dirty = false,
Type = "HAMMER",
VolumeName = StringHandlers.CToString(hammerSb.vol_label, Encoding),
VolumeSerial = hammerSb.vol_fsid.ToString()
};
@@ -130,11 +130,11 @@ namespace DiscImageChef.Filesystems
hammerSb.vol0_stat_freebigblocks * HAMMER_BIGBLOCK_SIZE).AppendLine();
sb.AppendFormat("Filesystem has {0} inode used", hammerSb.vol0_stat_inodes).AppendLine();
XmlFsType.Clusters = hammerSb.vol0_stat_bigblocks;
XmlFsType.FreeClusters = hammerSb.vol0_stat_freebigblocks;
XmlFsType.Clusters = hammerSb.vol0_stat_bigblocks;
XmlFsType.FreeClusters = hammerSb.vol0_stat_freebigblocks;
XmlFsType.FreeClustersSpecified = true;
XmlFsType.Files = hammerSb.vol0_stat_inodes;
XmlFsType.FilesSpecified = true;
XmlFsType.Files = hammerSb.vol0_stat_inodes;
XmlFsType.FilesSpecified = true;
}
// 0 ?
//sb.AppendFormat("Volume header CRC: 0x{0:X8}", afs_sb.vol_crc).AppendLine();
@@ -168,7 +168,8 @@ namespace DiscImageChef.Filesystems
/// <summary>identify filesystem type</summary>
public Guid vol_fstype;
/// <summary>filesystem label</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)] public byte[] vol_label;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
public byte[] vol_label;
/// <summary>volume number within filesystem</summary>
public int vol_no;
@@ -184,7 +185,8 @@ namespace DiscImageChef.Filesystems
/// <summary>the root volume number (must be 0)</summary>
public uint vol_rootvol;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] public uint[] vol_reserved;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public uint[] vol_reserved;
/*
* These fields are initialized and space is reserved in every
@@ -211,10 +213,12 @@ namespace DiscImageChef.Filesystems
/// Blockmaps for zones. Not all zones use a blockmap. Note that the entire root blockmap is cached in the
/// hammer_mount structure.
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public HammerBlockMap[] vol0_blockmap;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public HammerBlockMap[] vol0_blockmap;
/// <summary>Array of zone-2 addresses for undo FIFO.</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)] public hammer_off_t[] vol0_undo_array;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public hammer_off_t[] vol0_undo_array;
}
[SuppressMessage("ReSharper", "InconsistentNaming")]
@@ -229,7 +233,7 @@ namespace DiscImageChef.Filesystems
public hammer_off_t next_offset;
/// <summary>zone-X offset only used by zone-3</summary>
public hammer_off_t alloc_offset;
public uint reserved01;
public uint reserved01;
public hammer_crc_t entry_crc;
}
}

View File

@@ -103,7 +103,7 @@ namespace DiscImageChef.Filesystems
sb.AppendFormat("Spareblock magic2: 0x{0:X8} (Should be 0xFA5229C5)", hpfsSp.magic2).AppendLine();
}
sb.AppendFormat("OEM name: {0}", StringHandlers.CToString(hpfsBpb.oem_name)).AppendLine();
sb.AppendFormat("OEM name: {0}", StringHandlers.CToString(hpfsBpb.oem_name)).AppendLine();
sb.AppendFormat("{0} bytes per sector", hpfsBpb.bps).AppendLine();
// sb.AppendFormat("{0} sectors per cluster", hpfs_bpb.spc).AppendLine();
// sb.AppendFormat("{0} reserved sectors", hpfs_bpb.rsectors).AppendLine();
@@ -114,70 +114,63 @@ namespace DiscImageChef.Filesystems
// sb.AppendFormat("{0} sectors per FAT", hpfs_bpb.spfat).AppendLine();
// sb.AppendFormat("{0} sectors per track", hpfs_bpb.sptrk).AppendLine();
// sb.AppendFormat("{0} heads", hpfs_bpb.heads).AppendLine();
sb.AppendFormat("{0} sectors hidden before BPB", hpfsBpb.hsectors).AppendLine();
sb.AppendFormat("{0} sectors hidden before BPB", hpfsBpb.hsectors).AppendLine();
sb.AppendFormat("{0} sectors on volume ({1} bytes)", hpfsSb.sectors, hpfsSb.sectors * hpfsBpb.bps)
.AppendLine();
// sb.AppendFormat("{0} sectors on volume ({1} bytes)", hpfs_bpb.big_sectors, hpfs_bpb.big_sectors * hpfs_bpb.bps).AppendLine();
sb.AppendFormat("BIOS Drive Number: 0x{0:X2}", hpfsBpb.drive_no).AppendLine();
sb.AppendFormat("NT Flags: 0x{0:X2}", hpfsBpb.nt_flags).AppendLine();
sb.AppendFormat("Signature: 0x{0:X2}", hpfsBpb.signature).AppendLine();
sb.AppendFormat("Serial number: 0x{0:X8}", hpfsBpb.serial_no).AppendLine();
sb.AppendFormat("Volume label: {0}", StringHandlers.CToString(hpfsBpb.volume_label, Encoding))
.AppendLine();
sb.AppendFormat("NT Flags: 0x{0:X2}", hpfsBpb.nt_flags).AppendLine();
sb.AppendFormat("Signature: 0x{0:X2}", hpfsBpb.signature).AppendLine();
sb.AppendFormat("Serial number: 0x{0:X8}", hpfsBpb.serial_no).AppendLine();
sb.AppendFormat("Volume label: {0}", StringHandlers.CToString(hpfsBpb.volume_label, Encoding)).AppendLine();
// sb.AppendFormat("Filesystem type: \"{0}\"", hpfs_bpb.fs_type).AppendLine();
DateTime lastChk = DateHandlers.UnixToDateTime(hpfsSb.last_chkdsk);
DateTime lastOptim = DateHandlers.UnixToDateTime(hpfsSb.last_optim);
sb.AppendFormat("HPFS version: {0}", hpfsSb.version)
.AppendLine();
sb.AppendFormat("Functional version: {0}", hpfsSb.func_version)
.AppendLine();
sb.AppendFormat("Sector of root directory FNode: {0}", hpfsSb.root_fnode)
.AppendLine();
sb.AppendFormat("{0} sectors are marked bad", hpfsSb.badblocks)
.AppendLine();
sb.AppendFormat("Sector of free space bitmaps: {0}", hpfsSb.bitmap_lsn)
.AppendLine();
sb.AppendFormat("Sector of bad blocks list: {0}", hpfsSb.badblock_lsn)
.AppendLine();
sb.AppendFormat("HPFS version: {0}", hpfsSb.version).AppendLine();
sb.AppendFormat("Functional version: {0}", hpfsSb.func_version).AppendLine();
sb.AppendFormat("Sector of root directory FNode: {0}", hpfsSb.root_fnode).AppendLine();
sb.AppendFormat("{0} sectors are marked bad", hpfsSb.badblocks).AppendLine();
sb.AppendFormat("Sector of free space bitmaps: {0}", hpfsSb.bitmap_lsn).AppendLine();
sb.AppendFormat("Sector of bad blocks list: {0}", hpfsSb.badblock_lsn).AppendLine();
if(hpfsSb.last_chkdsk > 0) sb.AppendFormat("Date of last integrity check: {0}", lastChk).AppendLine();
else sb.AppendLine("Filesystem integrity has never been checked");
if(hpfsSb.last_optim > 0) sb.AppendFormat("Date of last optimization {0}", lastOptim).AppendLine();
else sb.AppendLine("Filesystem has never been optimized");
sb.AppendFormat("Directory band has {0} sectors", hpfsSb.dband_sectors).AppendLine();
sb.AppendFormat("Directory band starts at sector {0}", hpfsSb.dband_start).AppendLine();
sb.AppendFormat("Directory band ends at sector {0}", hpfsSb.dband_last).AppendLine();
sb.AppendFormat("Directory band has {0} sectors", hpfsSb.dband_sectors).AppendLine();
sb.AppendFormat("Directory band starts at sector {0}", hpfsSb.dband_start).AppendLine();
sb.AppendFormat("Directory band ends at sector {0}", hpfsSb.dband_last).AppendLine();
sb.AppendFormat("Sector of directory band bitmap: {0}", hpfsSb.dband_bitmap).AppendLine();
sb.AppendFormat("Sector of ACL directory: {0}", hpfsSb.acl_start).AppendLine();
sb.AppendFormat("Sector of ACL directory: {0}", hpfsSb.acl_start).AppendLine();
sb.AppendFormat("Sector of Hotfix directory: {0}", hpfsSp.hotfix_start).AppendLine();
sb.AppendFormat("{0} used Hotfix entries", hpfsSp.hotfix_used).AppendLine();
sb.AppendFormat("{0} total Hotfix entries", hpfsSp.hotfix_entries).AppendLine();
sb.AppendFormat("{0} free spare DNodes", hpfsSp.spare_dnodes_free).AppendLine();
sb.AppendFormat("{0} total spare DNodes", hpfsSp.spare_dnodes).AppendLine();
sb.AppendFormat("Sector of Hotfix directory: {0}", hpfsSp.hotfix_start).AppendLine();
sb.AppendFormat("{0} used Hotfix entries", hpfsSp.hotfix_used).AppendLine();
sb.AppendFormat("{0} total Hotfix entries", hpfsSp.hotfix_entries).AppendLine();
sb.AppendFormat("{0} free spare DNodes", hpfsSp.spare_dnodes_free).AppendLine();
sb.AppendFormat("{0} total spare DNodes", hpfsSp.spare_dnodes).AppendLine();
sb.AppendFormat("Sector of codepage directory: {0}", hpfsSp.codepage_lsn).AppendLine();
sb.AppendFormat("{0} codepages used in the volume", hpfsSp.codepages).AppendLine();
sb.AppendFormat("SuperBlock CRC32: {0:X8}", hpfsSp.sb_crc32).AppendLine();
sb.AppendFormat("SpareBlock CRC32: {0:X8}", hpfsSp.sp_crc32).AppendLine();
sb.AppendFormat("{0} codepages used in the volume", hpfsSp.codepages).AppendLine();
sb.AppendFormat("SuperBlock CRC32: {0:X8}", hpfsSp.sb_crc32).AppendLine();
sb.AppendFormat("SpareBlock CRC32: {0:X8}", hpfsSp.sp_crc32).AppendLine();
sb.AppendLine("Flags:");
sb.AppendLine((hpfsSp.flags1 & 0x01) == 0x01 ? "Filesystem is dirty." : "Filesystem is clean.");
if((hpfsSp.flags1 & 0x02) == 0x02) sb.AppendLine("Spare directory blocks are in use");
if((hpfsSp.flags1 & 0x04) == 0x04) sb.AppendLine("Hotfixes are in use");
if((hpfsSp.flags1 & 0x08) == 0x08) sb.AppendLine("Disk contains bad sectors");
if((hpfsSp.flags1 & 0x10) == 0x10) sb.AppendLine("Disk has a bad bitmap");
if((hpfsSp.flags1 & 0x20) == 0x20) sb.AppendLine("Filesystem was formatted fast");
if((hpfsSp.flags1 & 0x40) == 0x40) sb.AppendLine("Unknown flag 0x40 on flags1 is active");
if((hpfsSp.flags1 & 0x80) == 0x80) sb.AppendLine("Filesystem has been mounted by an old IFS");
if((hpfsSp.flags2 & 0x01) == 0x01) sb.AppendLine("Install DASD limits");
if((hpfsSp.flags2 & 0x02) == 0x02) sb.AppendLine("Resync DASD limits");
if((hpfsSp.flags2 & 0x04) == 0x04) sb.AppendLine("DASD limits are operational");
if((hpfsSp.flags2 & 0x08) == 0x08) sb.AppendLine("Multimedia is active");
if((hpfsSp.flags2 & 0x10) == 0x10) sb.AppendLine("DCE ACLs are active");
if((hpfsSp.flags2 & 0x20) == 0x20) sb.AppendLine("DASD limits are dirty");
if((hpfsSp.flags2 & 0x40) == 0x40) sb.AppendLine("Unknown flag 0x40 on flags2 is active");
if((hpfsSp.flags2 & 0x80) == 0x80) sb.AppendLine("Unknown flag 0x80 on flags2 is active");
if((hpfsSp.flags1 & 0x02) == 0x02) sb.AppendLine("Spare directory blocks are in use");
if((hpfsSp.flags1 & 0x04) == 0x04) sb.AppendLine("Hotfixes are in use");
if((hpfsSp.flags1 & 0x08) == 0x08) sb.AppendLine("Disk contains bad sectors");
if((hpfsSp.flags1 & 0x10) == 0x10) sb.AppendLine("Disk has a bad bitmap");
if((hpfsSp.flags1 & 0x20) == 0x20) sb.AppendLine("Filesystem was formatted fast");
if((hpfsSp.flags1 & 0x40) == 0x40) sb.AppendLine("Unknown flag 0x40 on flags1 is active");
if((hpfsSp.flags1 & 0x80) == 0x80) sb.AppendLine("Filesystem has been mounted by an old IFS");
if((hpfsSp.flags2 & 0x01) == 0x01) sb.AppendLine("Install DASD limits");
if((hpfsSp.flags2 & 0x02) == 0x02) sb.AppendLine("Resync DASD limits");
if((hpfsSp.flags2 & 0x04) == 0x04) sb.AppendLine("DASD limits are operational");
if((hpfsSp.flags2 & 0x08) == 0x08) sb.AppendLine("Multimedia is active");
if((hpfsSp.flags2 & 0x10) == 0x10) sb.AppendLine("DCE ACLs are active");
if((hpfsSp.flags2 & 0x20) == 0x20) sb.AppendLine("DASD limits are dirty");
if((hpfsSp.flags2 & 0x40) == 0x40) sb.AppendLine("Unknown flag 0x40 on flags2 is active");
if((hpfsSp.flags2 & 0x80) == 0x80) sb.AppendLine("Unknown flag 0x80 on flags2 is active");
XmlFsType = new FileSystemType();
@@ -185,8 +178,8 @@ namespace DiscImageChef.Filesystems
if(hpfsBpb.jump[0] == 0xEB && hpfsBpb.jump[1] > 0x3C && hpfsBpb.jump[1] < 0x80 &&
hpfsBpb.signature2 == 0xAA55)
{
XmlFsType.Bootable = true;
string bootChk = Sha1Context.Data(hpfsBpb.boot_code, out byte[] _);
XmlFsType.Bootable = true;
string bootChk = Sha1Context.Data(hpfsBpb.boot_code, out byte[] _);
sb.AppendLine("Volume is bootable");
sb.AppendFormat("Boot code's SHA1: {0}", bootChk).AppendLine();
}

View File

@@ -31,7 +31,6 @@
// ****************************************************************************/
using System;
using System.Collections.Generic;
using System.Text;
using DiscImageChef.CommonTypes;
using DiscImageChef.DiscImages;

View File

@@ -36,7 +36,7 @@ namespace DiscImageChef.Filesystems.ISO9660
{
public partial class ISO9660
{
const ushort AAIP_MAGIC = 0x414C; // "AL"
const ushort AAIP_MAGIC = 0x414C; // "AL"
const ushort AAIP_MAGIC_OLD = 0x4141; // "AA"
[Flags]

View File

@@ -41,8 +41,8 @@ namespace DiscImageChef.Filesystems.ISO9660
[Flags]
enum AmigaFlags : byte
{
Protection = 1 << 0,
Comment = 1 << 1,
Protection = 1 << 0,
Comment = 1 << 1,
CommentContinues = 1 << 2
}
@@ -50,26 +50,26 @@ namespace DiscImageChef.Filesystems.ISO9660
enum AmigaMultiuser : byte
{
GroupDelete = 1 << 0,
GroupExec = 1 << 1,
GroupWrite = 1 << 2,
GroupRead = 1 << 3,
GroupExec = 1 << 1,
GroupWrite = 1 << 2,
GroupRead = 1 << 3,
OtherDelete = 1 << 4,
OtherExec = 1 << 5,
OtherWrite = 1 << 6,
OtherRead = 1 << 7
OtherExec = 1 << 5,
OtherWrite = 1 << 6,
OtherRead = 1 << 7
}
[Flags]
enum AmigaAttributes : byte
{
OwnerDelete = 1 << 0,
OwnerExec = 1 << 1,
OwnerWrite = 1 << 2,
OwnerRead = 1 << 3,
Archive = 1 << 4,
Reentrant = 1 << 5,
Script = 1 << 6,
Reserved = 1 << 7
OwnerExec = 1 << 1,
OwnerWrite = 1 << 2,
OwnerRead = 1 << 3,
Archive = 1 << 4,
Reentrant = 1 << 5,
Script = 1 << 6,
Reserved = 1 << 7
}
}
}

View File

@@ -34,23 +34,23 @@ namespace DiscImageChef.Filesystems.ISO9660
{
public partial class ISO9660
{
const ushort APPLE_MAGIC = 0x4141; // "AA"
const ushort APPLE_MAGIC = 0x4141; // "AA"
const ushort APPLE_MAGIC_OLD = 0x4241; // "BA"
enum AppleId : byte
{
ProDOS = 1,
HFS = 2
HFS = 2
}
enum AppleOldId : byte
{
ProDOS = 1,
TypeCreator = 2,
TypeCreatorBundle = 3,
TypeCreatorIcon = 4,
ProDOS = 1,
TypeCreator = 2,
TypeCreatorBundle = 3,
TypeCreatorIcon = 4,
TypeCreatorIconBundle = 5,
HFS = 6
HFS = 6
}
}
}

View File

@@ -54,14 +54,14 @@ namespace DiscImageChef.Filesystems.ISO9660
[Flags]
enum CdiAttributes : ushort
{
OwnerRead = 1 << 0,
OwnerRead = 1 << 0,
OwnerExecute = 1 << 2,
GroupRead = 1 << 4,
GroupRead = 1 << 4,
GroupExecute = 1 << 6,
OtherRead = 1 << 8,
OtherRead = 1 << 8,
OtherExecute = 1 << 10,
DigitalAudio = 1 << 14,
Directory = 1 << 15
Directory = 1 << 15
}
}
}

View File

@@ -36,42 +36,42 @@ namespace DiscImageChef.Filesystems.ISO9660
{
public partial class ISO9660
{
const ushort EL_TORITO_MAGIC = 0xAA55;
const int EL_TORITO_ENTRY_SIZE = 32;
const ushort EL_TORITO_MAGIC = 0xAA55;
const int EL_TORITO_ENTRY_SIZE = 32;
enum ElToritoIndicator : byte
{
Header = 1,
Extension = 0x44,
Bootable = 0x88,
Header = 1,
Extension = 0x44,
Bootable = 0x88,
MoreHeaders = 0x90,
LastHeader = 0x91
LastHeader = 0x91
}
enum ElToritoPlatform : byte
{
x86 = 0,
PowerPC = 1,
x86 = 0,
PowerPC = 1,
Macintosh = 2,
EFI = 0xef
EFI = 0xef
}
enum ElToritoEmulation : byte
{
None = 0,
None = 0,
Md2hd = 1,
Mf2hd = 2,
Mf2ed = 3,
Hdd = 4
Hdd = 4
}
[Flags]
enum ElToritoFlags : byte
{
Reserved = 0x10,
Reserved = 0x10,
Continued = 0x20,
ATAPI = 0x40,
SCSI = 0x08
ATAPI = 0x40,
SCSI = 0x08
}
}
}

View File

@@ -41,39 +41,39 @@ namespace DiscImageChef.Filesystems.ISO9660
[Flags]
enum FileFlags : byte
{
Hidden = 0x01,
Directory = 0x02,
Associated = 0x04,
Record = 0x08,
Protected = 0x10,
Hidden = 0x01,
Directory = 0x02,
Associated = 0x04,
Record = 0x08,
Protected = 0x10,
MultiExtent = 0x80
}
[Flags]
enum Permissions : ushort
{
SystemRead = 0x01,
SystemRead = 0x01,
SystemExecute = 0x04,
OwnerRead = 0x10,
OwnerExecute = 0x40,
GroupRead = 0x100,
GroupExecute = 0x400,
OtherRead = 0x1000,
OtherExecute = 0x4000
OwnerRead = 0x10,
OwnerExecute = 0x40,
GroupRead = 0x100,
GroupExecute = 0x400,
OtherRead = 0x1000,
OtherExecute = 0x4000
}
enum RecordFormat : byte
{
Unspecified = 0,
FixedLength = 1,
VariableLength = 2,
Unspecified = 0,
FixedLength = 1,
VariableLength = 2,
VariableLengthAlternate = 3
}
enum RecordAttribute : byte
{
LFCR = 0,
ISO1539 = 1,
LFCR = 0,
ISO1539 = 1,
ControlContained = 2
}
}

View File

@@ -36,39 +36,39 @@ namespace DiscImageChef.Filesystems.ISO9660
{
public partial class ISO9660
{
const ushort RRIP_MAGIC = 0x5252; // "RR"
const ushort RRIP_MAGIC = 0x5252; // "RR"
const ushort RRIP_POSIX_ATTRIBUTES = 0x5058; // "PX"
const ushort RRIP_POSIX_DEV_NO = 0x504E; // "PN"
const ushort RRIP_SYMLINK = 0x534C; // "SL"
const ushort RRIP_NAME = 0x4E4D; // "NM"
const ushort RRIP_CHILDLINK = 0x434C; // "CL"
const ushort RRIP_PARENTLINK = 0x504C; // "PL"
const ushort RRIP_RELOCATED_DIR = 0x5245; // "RE"
const ushort RRIP_TIMESTAMPS = 0x5446; // "TF"
const ushort RRIP_SPARSE = 0x5346; // "SF"
const ushort RRIP_POSIX_DEV_NO = 0x504E; // "PN"
const ushort RRIP_SYMLINK = 0x534C; // "SL"
const ushort RRIP_NAME = 0x4E4D; // "NM"
const ushort RRIP_CHILDLINK = 0x434C; // "CL"
const ushort RRIP_PARENTLINK = 0x504C; // "PL"
const ushort RRIP_RELOCATED_DIR = 0x5245; // "RE"
const ushort RRIP_TIMESTAMPS = 0x5446; // "TF"
const ushort RRIP_SPARSE = 0x5346; // "SF"
[Flags]
enum PosixMode : uint
{
OwnerRead = 0x100,
OwnerWrite = 0x80,
OwnerRead = 0x100,
OwnerWrite = 0x80,
OwnerExecute = 0x40,
GroupRead = 0x20,
GroupWrite = 0x10,
GroupRead = 0x20,
GroupWrite = 0x10,
GroupExecute = 0x8,
OtherRead = 0x4,
OtherWrite = 0x2,
OtherRead = 0x4,
OtherWrite = 0x2,
OtherExecute = 0x1,
SetUID = 0x800,
SetGid = 0x400,
IsVTX = 0x200,
Socket = 0xC000,
Symlink = 0xA000,
Regular = 0x8000,
Block = 0x6000,
Character = 0x2000,
Directory = 0x4000,
Pipe = 0x1000
SetUID = 0x800,
SetGid = 0x400,
IsVTX = 0x200,
Socket = 0xC000,
Symlink = 0xA000,
Regular = 0x8000,
Block = 0x6000,
Character = 0x2000,
Directory = 0x4000,
Pipe = 0x1000
}
[Flags]
@@ -80,34 +80,34 @@ namespace DiscImageChef.Filesystems.ISO9660
[Flags]
enum SymlinkComponentFlags : byte
{
Continue = 1,
Current = 2,
Parent = 4,
Root = 8,
Mountpoint = 16,
Continue = 1,
Current = 2,
Parent = 4,
Root = 8,
Mountpoint = 16,
Networkname = 32
}
[Flags]
enum AlternateNameFlags : byte
{
Continue = 1,
Current = 2,
Parent = 4,
Continue = 1,
Current = 2,
Parent = 4,
Networkname = 32
}
[Flags]
enum TimestampFlags : byte
{
Creation = 1 << 0,
Modification = 1 << 1,
Access = 1 << 2,
Creation = 1 << 0,
Modification = 1 << 1,
Access = 1 << 2,
AttributeChange = 1 << 3,
Backup = 1 << 4,
Expiration = 1 << 5,
Effective = 1 << 6,
LongFormat = 1 << 7
Backup = 1 << 4,
Expiration = 1 << 5,
Effective = 1 << 6,
LongFormat = 1 << 7
}
}
}

View File

@@ -35,11 +35,11 @@ namespace DiscImageChef.Filesystems.ISO9660
public partial class ISO9660
{
const ushort SUSP_CONTINUATION = 0x4345; // "CE"
const ushort SUSP_PADDING = 0x5044; // "PD"
const ushort SUSP_INDICATOR = 0x5350; // "SP"
const ushort SUSP_TERMINATOR = 0x5354; // "ST"
const ushort SUSP_REFERENCE = 0x4552; // "ER"
const ushort SUSP_SELECTOR = 0x4553; // "ES"
const ushort SUSP_MAGIC = 0xBEEF;
const ushort SUSP_PADDING = 0x5044; // "PD"
const ushort SUSP_INDICATOR = 0x5350; // "SP"
const ushort SUSP_TERMINATOR = 0x5354; // "ST"
const ushort SUSP_REFERENCE = 0x4552; // "ER"
const ushort SUSP_SELECTOR = 0x4553; // "ES"
const ushort SUSP_MAGIC = 0xBEEF;
}
}

View File

@@ -41,17 +41,17 @@ namespace DiscImageChef.Filesystems.ISO9660
[Flags]
enum XaAttributes : ushort
{
SystemRead = 0x01,
SystemRead = 0x01,
SystemExecute = 0x04,
OwnerRead = 0x10,
OwnerExecute = 0x40,
GroupRead = 0x100,
GroupExecute = 0x400,
Mode2Form1 = 0x800,
Mode2Form2 = 0x1000,
Interleaved = 0x2000,
Cdda = 0x4000,
Directory = 0x8000
OwnerRead = 0x10,
OwnerExecute = 0x40,
GroupRead = 0x100,
GroupExecute = 0x400,
Mode2Form1 = 0x800,
Mode2Form2 = 0x1000,
Interleaved = 0x2000,
Cdda = 0x4000,
Directory = 0x8000
}
}
}

View File

@@ -34,9 +34,9 @@ namespace DiscImageChef.Filesystems.ISO9660
{
public partial class ISO9660
{
const ulong ZISO_HEADER_MAGIC = 0x37E45396C9DBD607;
const ulong ZISO_HEADER_CIGAM = 0x07D6DBC99653E437;
const ushort ZISO_MAGIC = 0x5A46; // "ZF"
const ushort ZISO_PAGED_ZLIB = 0x707A; // "pz"
const ulong ZISO_HEADER_MAGIC = 0x37E45396C9DBD607;
const ulong ZISO_HEADER_CIGAM = 0x07D6DBC99653E437;
const ushort ZISO_MAGIC = 0x5A46; // "ZF"
const ushort ZISO_PAGED_ZLIB = 0x707A; // "pz"
}
}

View File

@@ -40,8 +40,8 @@ namespace DiscImageChef.Filesystems.ISO9660
public partial class ISO9660 : IFilesystem
{
public FileSystemType XmlFsType { get; private set; }
public Encoding Encoding { get; private set; }
public string Name => "ISO9660 Filesystem";
public Guid Id => new Guid("d812f4d3-c357-400d-90fd-3b22ef786aa8");
public Encoding Encoding { get; private set; }
public string Name => "ISO9660 Filesystem";
public Guid Id => new Guid("d812f4d3-c357-400d-90fd-3b22ef786aa8");
}
}

View File

@@ -80,8 +80,8 @@ namespace DiscImageChef.Filesystems.ISO9660
public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
Encoding encoding)
{
Encoding = encoding ?? Encoding.ASCII;
information = "";
Encoding = encoding ?? Encoding.ASCII;
information = "";
StringBuilder isoMetadata = new StringBuilder();
byte[] vdMagic = new byte[5]; // Volume Descriptor magic "CD001"
byte[] hsMagic = new byte[5]; // Volume Descriptor magic "CDROM"
@@ -116,8 +116,8 @@ namespace DiscImageChef.Filesystems.ISO9660
DicConsole.DebugWriteLine("ISO9660 plugin", "Processing VD loop no. {0}", counter);
// Seek to Volume Descriptor
DicConsole.DebugWriteLine("ISO9660 plugin", "Reading sector {0}", 16 + counter + partition.Start);
byte[] vdSectorTmp = imagePlugin.ReadSector(16 + counter + partition.Start);
vdSector = new byte[vdSectorTmp.Length - xaOff];
byte[] vdSectorTmp = imagePlugin.ReadSector(16 + counter + partition.Start);
vdSector = new byte[vdSectorTmp.Length - xaOff];
Array.Copy(vdSectorTmp, xaOff, vdSector, 0, vdSector.Length);
byte vdType = vdSector[0 + hsOff]; // Volume Descriptor Type, should be 1 or 2.
@@ -199,7 +199,7 @@ namespace DiscImageChef.Filesystems.ISO9660
Marshal.FreeHGlobal(ptr);
// Check if this is Joliet
if(svd.escape_sequences[0] == '%' && svd.escape_sequences[1] == '/')
if(svd.escape_sequences[0] == '%' && svd.escape_sequences[1] == '/')
if(svd.escape_sequences[2] == '@' || svd.escape_sequences[2] == 'C' ||
svd.escape_sequences[2] == 'E')
jolietvd = svd;
@@ -225,10 +225,8 @@ namespace DiscImageChef.Filesystems.ISO9660
}
if(highSierra) decodedVd = DecodeVolumeDescriptor(hsvd.Value);
else if(cdi)
decodedVd = DecodeVolumeDescriptor(fsvd.Value);
else
decodedVd = DecodeVolumeDescriptor(pvd.Value);
else if(cdi) decodedVd = DecodeVolumeDescriptor(fsvd.Value);
else decodedVd = DecodeVolumeDescriptor(pvd.Value);
if(jolietvd != null) decodedJolietVd = DecodeJolietDescriptor(jolietvd.Value);
@@ -282,7 +280,7 @@ namespace DiscImageChef.Filesystems.ISO9660
Marshal.FreeHGlobal(ptr);
int saOff = Marshal.SizeOf(record) + record.name_len;
saOff += saOff % 2;
saOff += saOff % 2;
int saLen = record.length - saOff;
if(saLen > 0 && rootOff + saOff + saLen <= rootDir.Length)
@@ -320,9 +318,9 @@ namespace DiscImageChef.Filesystems.ISO9660
break;
// Not easy, contains size field
case APPLE_MAGIC_OLD:
apple = true;
apple = true;
AppleOldId appleId = (AppleOldId)sa[saOff + 2];
noneFound = false;
noneFound = false;
switch(appleId)
{
@@ -366,7 +364,7 @@ namespace DiscImageChef.Filesystems.ISO9660
.ByteArrayToStructureBigEndian<ContinuationArea>(ce);
contareas.Add(ca);
break;
case SUSP_REFERENCE when saOff + sa[saOff + 2] <= saLen:
case SUSP_REFERENCE when saOff + sa[saOff + 2] <= saLen:
byte[] er = new byte[sa[saOff + 2]];
Array.Copy(sa, saOff, er, 0, er.Length);
refareas.Add(er);
@@ -385,9 +383,9 @@ namespace DiscImageChef.Filesystems.ISO9660
ziso |= nextSignature == ZISO_MAGIC;
amiga |= nextSignature == AMIGA_MAGIC;
aaip |= nextSignature == AAIP_MAGIC || nextSignature == AAIP_MAGIC_OLD &&
sa[saOff + 3] == 1 &&
sa[saOff + 2] >= 9;
aaip |= nextSignature == AAIP_MAGIC || nextSignature == AAIP_MAGIC_OLD &&
sa[saOff + 3] == 1 &&
sa[saOff + 2] >= 9;
saOff += sa[saOff + 2];
@@ -429,7 +427,7 @@ namespace DiscImageChef.Filesystems.ISO9660
if(caData[caOff + 3] == 1 && caData[caOff + 2] == 7) apple = true;
else apple |= caData[caOff + 3] != 1;
break;
case SUSP_REFERENCE when caOff + caData[caOff + 2] <= ca.ca_length_be:
case SUSP_REFERENCE when caOff + caData[caOff + 2] <= ca.ca_length_be:
byte[] er = new byte[caData[caOff + 2]];
Array.Copy(caData, caOff, er, 0, er.Length);
refareas.Add(er);
@@ -444,8 +442,8 @@ namespace DiscImageChef.Filesystems.ISO9660
ziso |= nextSignature == ZISO_MAGIC;
amiga |= nextSignature == AMIGA_MAGIC;
aaip |= nextSignature == AAIP_MAGIC || nextSignature == AAIP_MAGIC_OLD && caData[caOff + 3] == 1 &&
caData[caOff + 2] >= 9;
aaip |= nextSignature == AAIP_MAGIC || nextSignature == AAIP_MAGIC_OLD && caData[caOff + 3] == 1 &&
caData[caOff + 2] >= 9;
caOff += caData[caOff + 2];
}
@@ -460,17 +458,17 @@ namespace DiscImageChef.Filesystems.ISO9660
counter = 1;
foreach(byte[] erb in refareas)
{
ReferenceArea er = BigEndianMarshal.ByteArrayToStructureBigEndian<ReferenceArea>(erb);
string extId =
ReferenceArea er = BigEndianMarshal.ByteArrayToStructureBigEndian<ReferenceArea>(erb);
string extId =
Encoding.GetString(erb, Marshal.SizeOf(er), er.id_len);
string extDes =
Encoding.GetString(erb, Marshal.SizeOf(er) + er.id_len, er.des_len);
string extSrc =
Encoding.GetString(erb, Marshal.SizeOf(er) + er.id_len + er.des_len, er.src_len);
suspInformation.AppendFormat("Extension: {0}", counter).AppendLine();
suspInformation.AppendFormat("Extension: {0}", counter).AppendLine();
suspInformation.AppendFormat("\tID: {0}, version {1}", extId, er.ext_ver).AppendLine();
suspInformation.AppendFormat("\tDescription: {0}", extDes).AppendLine();
suspInformation.AppendFormat("\tSource: {0}", extSrc).AppendLine();
suspInformation.AppendFormat("\tDescription: {0}", extDes).AppendLine();
suspInformation.AppendFormat("\tSource: {0}", extSrc).AppendLine();
counter++;
}
}
@@ -482,10 +480,8 @@ namespace DiscImageChef.Filesystems.ISO9660
string fsFormat;
if(highSierra) fsFormat = "High Sierra Format";
else if(cdi)
fsFormat = "CD-i";
else
fsFormat = "ISO9660";
else if(cdi) fsFormat = "CD-i";
else fsFormat = "ISO9660";
isoMetadata.AppendFormat("{0} file system", fsFormat).AppendLine();
if(xaExtensions) isoMetadata.AppendLine("CD-ROM XA extensions present.");
@@ -519,14 +515,13 @@ namespace DiscImageChef.Filesystems.ISO9660
isoMetadata.AppendFormat("{0}------------------------------", cdi ? "---------------" : "").AppendLine();
isoMetadata.AppendFormat("{0}VOLUME DESCRIPTOR INFORMATION:", cdi ? "FILE STRUCTURE " : "").AppendLine();
isoMetadata.AppendFormat("{0}------------------------------", cdi ? "---------------" : "").AppendLine();
isoMetadata.AppendFormat("System identifier: {0}", decodedVd.SystemIdentifier).AppendLine();
isoMetadata.AppendFormat("Volume identifier: {0}", decodedVd.VolumeIdentifier).AppendLine();
isoMetadata.AppendFormat("Volume set identifier: {0}", decodedVd.VolumeSetIdentifier).AppendLine();
isoMetadata.AppendFormat("Publisher identifier: {0}", decodedVd.PublisherIdentifier).AppendLine();
isoMetadata.AppendFormat("Data preparer identifier: {0}", decodedVd.DataPreparerIdentifier)
.AppendLine();
isoMetadata.AppendFormat("System identifier: {0}", decodedVd.SystemIdentifier).AppendLine();
isoMetadata.AppendFormat("Volume identifier: {0}", decodedVd.VolumeIdentifier).AppendLine();
isoMetadata.AppendFormat("Volume set identifier: {0}", decodedVd.VolumeSetIdentifier).AppendLine();
isoMetadata.AppendFormat("Publisher identifier: {0}", decodedVd.PublisherIdentifier).AppendLine();
isoMetadata.AppendFormat("Data preparer identifier: {0}", decodedVd.DataPreparerIdentifier).AppendLine();
isoMetadata.AppendFormat("Application identifier: {0}", decodedVd.ApplicationIdentifier).AppendLine();
isoMetadata.AppendFormat("Volume creation date: {0}", decodedVd.CreationTime).AppendLine();
isoMetadata.AppendFormat("Volume creation date: {0}", decodedVd.CreationTime).AppendLine();
if(decodedVd.HasModificationTime)
isoMetadata.AppendFormat("Volume modification date: {0}", decodedVd.ModificationTime).AppendLine();
else isoMetadata.AppendFormat("Volume has not been modified.").AppendLine();
@@ -544,12 +539,11 @@ namespace DiscImageChef.Filesystems.ISO9660
isoMetadata.AppendLine("-------------------------------------");
isoMetadata.AppendLine("JOLIET VOLUME DESCRIPTOR INFORMATION:");
isoMetadata.AppendLine("-------------------------------------");
isoMetadata.AppendFormat("System identifier: {0}", decodedJolietVd.SystemIdentifier).AppendLine();
isoMetadata.AppendFormat("Volume identifier: {0}", decodedJolietVd.VolumeIdentifier).AppendLine();
isoMetadata.AppendFormat("System identifier: {0}", decodedJolietVd.SystemIdentifier).AppendLine();
isoMetadata.AppendFormat("Volume identifier: {0}", decodedJolietVd.VolumeIdentifier).AppendLine();
isoMetadata.AppendFormat("Volume set identifier: {0}", decodedJolietVd.VolumeSetIdentifier)
.AppendLine();
isoMetadata.AppendFormat("Publisher identifier: {0}", decodedJolietVd.PublisherIdentifier)
.AppendLine();
isoMetadata.AppendFormat("Publisher identifier: {0}", decodedJolietVd.PublisherIdentifier).AppendLine();
isoMetadata.AppendFormat("Data preparer identifier: {0}", decodedJolietVd.DataPreparerIdentifier)
.AppendLine();
isoMetadata.AppendFormat("Application identifier: {0}", decodedJolietVd.ApplicationIdentifier)
@@ -599,8 +593,7 @@ namespace DiscImageChef.Filesystems.ISO9660
initialEntry.sector_count);
byte[] bootImage =
initialEntry.load_rba + partition.Start + initialEntry.sector_count -
1 <= partition.End
initialEntry.load_rba + partition.Start + initialEntry.sector_count - 1 <= partition.End
? imagePlugin.ReadSectors(initialEntry.load_rba + partition.Start, initialEntry.sector_count)
: null;
@@ -653,9 +646,8 @@ namespace DiscImageChef.Filesystems.ISO9660
const int SECTION_COUNTER = 2;
while(toritoOff < vdSector.Length &&
(vdSector[toritoOff] == (byte)ElToritoIndicator.Header ||
vdSector[toritoOff] == (byte)ElToritoIndicator.LastHeader))
while(toritoOff < vdSector.Length && (vdSector[toritoOff] == (byte)ElToritoIndicator.Header ||
vdSector[toritoOff] == (byte)ElToritoIndicator.LastHeader))
{
ptr = Marshal.AllocHGlobal(EL_TORITO_ENTRY_SIZE);
Marshal.Copy(vdSector, toritoOff, ptr, EL_TORITO_ENTRY_SIZE);
@@ -682,8 +674,7 @@ namespace DiscImageChef.Filesystems.ISO9660
if(sectionEntry.bootable == ElToritoIndicator.Bootable)
{
bootImage =
sectionEntry.load_rba + partition.Start +
sectionEntry.sector_count - 1 <= partition.End
sectionEntry.load_rba + partition.Start + sectionEntry.sector_count - 1 <= partition.End
? imagePlugin.ReadSectors(sectionEntry.load_rba + partition.Start,
sectionEntry.sector_count)
: null;

View File

@@ -39,9 +39,9 @@ namespace DiscImageChef.Filesystems.ISO9660
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct AmigaEntry
{
public ushort signature;
public byte length;
public byte version;
public ushort signature;
public byte length;
public byte version;
public AmigaFlags flags;
// Followed by AmigaProtection if present
// Followed by length-prefixed string for comment if present
@@ -50,9 +50,9 @@ namespace DiscImageChef.Filesystems.ISO9660
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct AmigaProtection
{
public byte User;
public byte Reserved;
public AmigaMultiuser Multiuser;
public byte User;
public byte Reserved;
public AmigaMultiuser Multiuser;
public AmigaAttributes Protection;
}
}

View File

@@ -40,65 +40,66 @@ namespace DiscImageChef.Filesystems.ISO9660
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct AppleProDOSSystemUse
{
public ushort signature;
public byte length;
public ushort signature;
public byte length;
public AppleId id;
public byte type;
public ushort aux_type;
public byte type;
public ushort aux_type;
}
// Big-endian
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct AppleHFSSystemUse
{
public ushort signature;
public byte length;
public ushort signature;
public byte length;
public AppleId id;
public ushort type;
public ushort creator;
public ushort finder_flags;
public ushort type;
public ushort creator;
public ushort finder_flags;
}
// Little-endian
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct AppleProDOSOldSystemUse
{
public ushort signature;
public ushort signature;
public AppleOldId id;
public byte type;
public ushort aux_type;
public byte type;
public ushort aux_type;
}
// Big-endian
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct AppleHFSTypeCreatorSystemUse
{
public ushort signature;
public ushort signature;
public AppleOldId id;
public ushort type;
public ushort creator;
public ushort type;
public ushort creator;
}
// Big-endian
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct AppleHFSIconSystemUse
{
public ushort signature;
public ushort signature;
public AppleOldId id;
public ushort type;
public ushort creator;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)] public byte[] icon;
public ushort type;
public ushort creator;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public byte[] icon;
}
// Big-endian
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct AppleHFSOldSystemUse
{
public ushort signature;
public ushort signature;
public AppleOldId id;
public ushort type;
public ushort creator;
public ushort finder_flags;
public ushort type;
public ushort creator;
public ushort finder_flags;
}
}
}

View File

@@ -32,7 +32,6 @@
using System;
using System.Runtime.InteropServices;
using System.Text;
namespace DiscImageChef.Filesystems.ISO9660
{
@@ -42,40 +41,42 @@ namespace DiscImageChef.Filesystems.ISO9660
{
DecodedVolumeDescriptor decodedVD = new DecodedVolumeDescriptor
{
SystemIdentifier = StringHandlers.CToString(pvd.system_id).TrimEnd(),
VolumeIdentifier = StringHandlers.CToString(pvd.volume_id).TrimEnd(),
VolumeSetIdentifier = StringHandlers.CToString(pvd.volume_set_id).TrimEnd(),
PublisherIdentifier = StringHandlers.CToString(pvd.publisher_id).TrimEnd(),
SystemIdentifier = StringHandlers.CToString(pvd.system_id).TrimEnd(),
VolumeIdentifier = StringHandlers.CToString(pvd.volume_id).TrimEnd(),
VolumeSetIdentifier = StringHandlers.CToString(pvd.volume_set_id).TrimEnd(),
PublisherIdentifier = StringHandlers.CToString(pvd.publisher_id).TrimEnd(),
DataPreparerIdentifier = StringHandlers.CToString(pvd.preparer_id).TrimEnd(),
ApplicationIdentifier = StringHandlers.CToString(pvd.application_data).TrimEnd()
ApplicationIdentifier = StringHandlers.CToString(pvd.application_data).TrimEnd()
};
if(pvd.creation_date[0] == '0' || pvd.creation_date[0] == 0x00) decodedVD.CreationTime = DateTime.MinValue;
else decodedVD.CreationTime = DateHandlers.HighSierraToDateTime(pvd.creation_date);
else
decodedVD.CreationTime =
DateHandlers.HighSierraToDateTime(pvd.creation_date);
if(pvd.modification_date[0] == '0' || pvd.modification_date[0] == 0x00)
decodedVD.HasModificationTime = false;
else
{
decodedVD.HasModificationTime = true;
decodedVD.ModificationTime = DateHandlers.HighSierraToDateTime(pvd.modification_date);
decodedVD.ModificationTime = DateHandlers.HighSierraToDateTime(pvd.modification_date);
}
if(pvd.expiration_date[0] == '0' || pvd.expiration_date[0] == 0x00) decodedVD.HasExpirationTime = false;
else
{
decodedVD.HasExpirationTime = true;
decodedVD.ExpirationTime = DateHandlers.HighSierraToDateTime(pvd.expiration_date);
decodedVD.ExpirationTime = DateHandlers.HighSierraToDateTime(pvd.expiration_date);
}
if(pvd.effective_date[0] == '0' || pvd.effective_date[0] == 0x00) decodedVD.HasEffectiveTime = false;
else
{
decodedVD.HasEffectiveTime = true;
decodedVD.EffectiveTime = DateHandlers.HighSierraToDateTime(pvd.effective_date);
decodedVD.EffectiveTime = DateHandlers.HighSierraToDateTime(pvd.effective_date);
}
decodedVD.Blocks = pvd.volume_space_size;
decodedVD.Blocks = pvd.volume_space_size;
decodedVD.BlockSize = pvd.logical_block_size;
return decodedVD;
@@ -85,48 +86,70 @@ namespace DiscImageChef.Filesystems.ISO9660
struct FileStructureVolumeDescriptor
{
public byte type;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)] public byte[] id;
public byte version;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
public byte[] id;
public byte version;
public CdiVolumeFlags flags;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] public byte[] system_id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] public byte[] volume_id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)] public byte[] reserved1;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public byte[] system_id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public byte[] volume_id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)]
public byte[] reserved1;
public uint volume_space_size;
// Only used in SVDs
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] public byte[] escape_sequences;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public byte[] escape_sequences;
public ushort reserved2;
public ushort volume_set_size;
public ushort reserved3;
public ushort volume_sequence_number;
public ushort reserved4;
public ushort logical_block_size;
public uint reserved5;
public uint path_table_size;
public ulong reserved6;
public uint path_table_addr;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 38)] public byte[] reserved7;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)] public byte[] volume_set_id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)] public byte[] publisher_id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)] public byte[] preparer_id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)] public byte[] application_id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] public byte[] copyright_file_id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)] public byte[] reserved8;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] public byte[] abstract_file_id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)] public byte[] reserved9;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] public byte[] bibliographic_file_id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)] public byte[] reserved10;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public byte[] creation_date;
public uint reserved5;
public uint path_table_size;
public ulong reserved6;
public uint path_table_addr;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 38)]
public byte[] reserved7;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public byte[] volume_set_id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public byte[] publisher_id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public byte[] preparer_id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public byte[] application_id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public byte[] copyright_file_id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
public byte[] reserved8;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public byte[] abstract_file_id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
public byte[] reserved9;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public byte[] bibliographic_file_id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
public byte[] reserved10;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[] creation_date;
public byte reserved11;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public byte[] modification_date;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[] modification_date;
public byte reserved12;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public byte[] expiration_date;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[] expiration_date;
public byte reserved13;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public byte[] effective_date;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[] effective_date;
public byte reserved14;
public byte file_structure_version;
public byte reserved15;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 512)] public byte[] application_data;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 653)] public byte[] reserved16;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 512)]
public byte[] application_data;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 653)]
public byte[] reserved16;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
@@ -138,13 +161,14 @@ namespace DiscImageChef.Filesystems.ISO9660
public uint start_lbn;
public uint reserved2;
public uint size;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)] public byte[] date;
public byte reserved3;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
public byte[] date;
public byte reserved3;
public CdiFileFlags flags;
public ushort file_unit_size;
public ushort reserved4;
public ushort volume_sequence_number;
public byte name_len;
public ushort file_unit_size;
public ushort reserved4;
public ushort volume_sequence_number;
public byte name_len;
// Followed by name[name_len] and then CdiSystemArea until length arrives
}
@@ -152,11 +176,11 @@ namespace DiscImageChef.Filesystems.ISO9660
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct CdiSystemArea
{
public uint owner;
public uint owner;
public CdiAttributes attributes;
public ushort reserved1;
public byte file_no;
public byte reserved2;
public ushort reserved1;
public byte file_no;
public byte reserved2;
}
}
}

View File

@@ -38,21 +38,21 @@ namespace DiscImageChef.Filesystems.ISO9660
{
struct DecodedVolumeDescriptor
{
public string SystemIdentifier;
public string VolumeIdentifier;
public string VolumeSetIdentifier;
public string PublisherIdentifier;
public string DataPreparerIdentifier;
public string ApplicationIdentifier;
public string SystemIdentifier;
public string VolumeIdentifier;
public string VolumeSetIdentifier;
public string PublisherIdentifier;
public string DataPreparerIdentifier;
public string ApplicationIdentifier;
public DateTime CreationTime;
public bool HasModificationTime;
public bool HasModificationTime;
public DateTime ModificationTime;
public bool HasExpirationTime;
public bool HasExpirationTime;
public DateTime ExpirationTime;
public bool HasEffectiveTime;
public bool HasEffectiveTime;
public DateTime EffectiveTime;
public ushort BlockSize;
public uint Blocks;
public ushort BlockSize;
public uint Blocks;
}
}
}

View File

@@ -40,21 +40,26 @@ namespace DiscImageChef.Filesystems.ISO9660
struct ElToritoBootRecord
{
public byte type;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)] public byte[] id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
public byte[] id;
public byte version;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] public byte[] system_id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] public byte[] boot_id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public byte[] system_id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public byte[] boot_id;
public uint catalog_sector;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1974)] public byte[] boot_use;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1974)]
public byte[] boot_use;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct ElToritoValidationEntry
{
public ElToritoIndicator header_id;
public ElToritoPlatform platform_id;
public ushort reserved;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 24)] public byte[] developer_id;
public ElToritoPlatform platform_id;
public ushort reserved;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 24)]
public byte[] developer_id;
public ushort checksum;
public ushort signature;
}
@@ -64,21 +69,23 @@ namespace DiscImageChef.Filesystems.ISO9660
{
public ElToritoIndicator bootable;
public ElToritoEmulation boot_type;
public ushort load_seg;
public byte system_type;
public byte reserved1;
public ushort sector_count;
public uint load_rba;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)] public byte[] reserved2;
public ushort load_seg;
public byte system_type;
public byte reserved1;
public ushort sector_count;
public uint load_rba;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
public byte[] reserved2;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct ElToritoSectionHeaderEntry
{
public ElToritoIndicator header_id;
public ElToritoPlatform platform_id;
public ushort entries;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 28)] public byte[] identifier;
public ElToritoPlatform platform_id;
public ushort entries;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 28)]
public byte[] identifier;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
@@ -86,21 +93,23 @@ namespace DiscImageChef.Filesystems.ISO9660
{
public ElToritoIndicator bootable;
public ElToritoEmulation boot_type;
public ushort load_seg;
public byte system_type;
public byte reserved1;
public ushort sector_count;
public uint load_rba;
public byte selection_criteria_type;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 19)] public byte[] selection_criterias;
public ushort load_seg;
public byte system_type;
public byte reserved1;
public ushort sector_count;
public uint load_rba;
public byte selection_criteria_type;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 19)]
public byte[] selection_criterias;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct ElToritoSectionEntryExtension
{
public ElToritoIndicator extension_indicator;
public ElToritoFlags extension_flags;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 30)] public byte[] selection_criterias;
public ElToritoFlags extension_flags;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 30)]
public byte[] selection_criterias;
}
}
}

View File

@@ -42,40 +42,42 @@ namespace DiscImageChef.Filesystems.ISO9660
{
DecodedVolumeDescriptor decodedVD = new DecodedVolumeDescriptor
{
SystemIdentifier = Encoding.ASCII.GetString(pvd.system_id).TrimEnd().Trim('\0'),
VolumeIdentifier = Encoding.ASCII.GetString(pvd.volume_id).TrimEnd().Trim('\0'),
VolumeSetIdentifier = Encoding.ASCII.GetString(pvd.volume_set_id).TrimEnd().Trim('\0'),
PublisherIdentifier = Encoding.ASCII.GetString(pvd.publisher_id).TrimEnd().Trim('\0'),
SystemIdentifier = Encoding.ASCII.GetString(pvd.system_id).TrimEnd().Trim('\0'),
VolumeIdentifier = Encoding.ASCII.GetString(pvd.volume_id).TrimEnd().Trim('\0'),
VolumeSetIdentifier = Encoding.ASCII.GetString(pvd.volume_set_id).TrimEnd().Trim('\0'),
PublisherIdentifier = Encoding.ASCII.GetString(pvd.publisher_id).TrimEnd().Trim('\0'),
DataPreparerIdentifier = Encoding.ASCII.GetString(pvd.preparer_id).TrimEnd().Trim('\0'),
ApplicationIdentifier = Encoding.ASCII.GetString(pvd.application_data).TrimEnd().Trim('\0')
ApplicationIdentifier = Encoding.ASCII.GetString(pvd.application_data).TrimEnd().Trim('\0')
};
if(pvd.creation_date[0] == '0' || pvd.creation_date[0] == 0x00) decodedVD.CreationTime = DateTime.MinValue;
else decodedVD.CreationTime = DateHandlers.HighSierraToDateTime(pvd.creation_date);
else
decodedVD.CreationTime =
DateHandlers.HighSierraToDateTime(pvd.creation_date);
if(pvd.modification_date[0] == '0' || pvd.modification_date[0] == 0x00)
decodedVD.HasModificationTime = false;
else
{
decodedVD.HasModificationTime = true;
decodedVD.ModificationTime = DateHandlers.HighSierraToDateTime(pvd.modification_date);
decodedVD.ModificationTime = DateHandlers.HighSierraToDateTime(pvd.modification_date);
}
if(pvd.expiration_date[0] == '0' || pvd.expiration_date[0] == 0x00) decodedVD.HasExpirationTime = false;
else
{
decodedVD.HasExpirationTime = true;
decodedVD.ExpirationTime = DateHandlers.HighSierraToDateTime(pvd.expiration_date);
decodedVD.ExpirationTime = DateHandlers.HighSierraToDateTime(pvd.expiration_date);
}
if(pvd.effective_date[0] == '0' || pvd.effective_date[0] == 0x00) decodedVD.HasEffectiveTime = false;
else
{
decodedVD.HasEffectiveTime = true;
decodedVD.EffectiveTime = DateHandlers.HighSierraToDateTime(pvd.effective_date);
decodedVD.EffectiveTime = DateHandlers.HighSierraToDateTime(pvd.effective_date);
}
decodedVD.Blocks = pvd.volume_space_size;
decodedVD.Blocks = pvd.volume_space_size;
decodedVD.BlockSize = pvd.logical_block_size;
return decodedVD;
@@ -87,48 +89,64 @@ namespace DiscImageChef.Filesystems.ISO9660
public uint volume_lbn;
public uint volume_lbn_be;
public byte type;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)] public byte[] id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
public byte[] id;
public byte version;
// Only used in SVDs
public byte flags;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] public byte[] system_id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] public byte[] volume_id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public byte[] system_id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public byte[] volume_id;
public ulong reserved1;
public uint volume_space_size;
public uint volume_space_size_be;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] public byte[] escape_sequences;
public ushort volume_set_size;
public ushort volume_set_size_be;
public ushort volume_sequence_number;
public ushort volume_sequence_number_be;
public ushort logical_block_size;
public ushort logical_block_size_be;
public uint path_table_size;
public uint path_table_size_be;
public uint manditory_path_table_lsb;
public uint opt_path_table_lsb_1;
public uint opt_path_table_lsb_2;
public uint opt_path_table_lsb_3;
public uint manditory_path_table_msb;
public uint opt_path_table_msb_1;
public uint opt_path_table_msb_2;
public uint opt_path_table_msb_3;
public uint volume_space_size;
public uint volume_space_size_be;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public byte[] escape_sequences;
public ushort volume_set_size;
public ushort volume_set_size_be;
public ushort volume_sequence_number;
public ushort volume_sequence_number_be;
public ushort logical_block_size;
public ushort logical_block_size_be;
public uint path_table_size;
public uint path_table_size_be;
public uint manditory_path_table_lsb;
public uint opt_path_table_lsb_1;
public uint opt_path_table_lsb_2;
public uint opt_path_table_lsb_3;
public uint manditory_path_table_msb;
public uint opt_path_table_msb_1;
public uint opt_path_table_msb_2;
public uint opt_path_table_msb_3;
public HighSierraDirectoryRecord root_directory_record;
public byte root_directory_name;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)] public byte[] volume_set_id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)] public byte[] publisher_id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)] public byte[] preparer_id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)] public byte[] application_id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] public byte[] copyright_file_id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] public byte[] abstract_file_id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public byte[] creation_date;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public byte[] modification_date;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public byte[] expiration_date;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public byte[] effective_date;
public byte root_directory_name;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public byte[] volume_set_id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public byte[] publisher_id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public byte[] preparer_id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public byte[] application_id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public byte[] copyright_file_id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public byte[] abstract_file_id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[] creation_date;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[] modification_date;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[] expiration_date;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[] effective_date;
public byte file_structure_version;
public byte reserved2;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 512)] public byte[] application_data;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 680)] public byte[] reserved3;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 512)]
public byte[] application_data;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 680)]
public byte[] reserved3;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
@@ -140,14 +158,15 @@ namespace DiscImageChef.Filesystems.ISO9660
public uint extent_be;
public uint size;
public uint size_be;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)] public byte[] date;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
public byte[] date;
public FileFlags flags;
public byte reserved;
public byte interleave_size;
public byte interleave;
public ushort volume_sequence_number;
public ushort volume_sequence_number_be;
public byte name_len;
public byte reserved;
public byte interleave_size;
public byte interleave;
public ushort volume_sequence_number;
public ushort volume_sequence_number_be;
public byte name_len;
// Followed by name[name_len] and then system area until length arrives
}
}

View File

@@ -32,7 +32,6 @@
using System;
using System.Runtime.InteropServices;
using System.Text;
namespace DiscImageChef.Filesystems.ISO9660
{
@@ -42,40 +41,42 @@ namespace DiscImageChef.Filesystems.ISO9660
{
DecodedVolumeDescriptor decodedVD = new DecodedVolumeDescriptor
{
SystemIdentifier = StringHandlers.CToString(pvd.system_id).TrimEnd(),
VolumeIdentifier = StringHandlers.CToString(pvd.volume_id).TrimEnd(),
VolumeSetIdentifier = StringHandlers.CToString(pvd.volume_set_id).TrimEnd(),
PublisherIdentifier = StringHandlers.CToString(pvd.publisher_id).TrimEnd(),
SystemIdentifier = StringHandlers.CToString(pvd.system_id).TrimEnd(),
VolumeIdentifier = StringHandlers.CToString(pvd.volume_id).TrimEnd(),
VolumeSetIdentifier = StringHandlers.CToString(pvd.volume_set_id).TrimEnd(),
PublisherIdentifier = StringHandlers.CToString(pvd.publisher_id).TrimEnd(),
DataPreparerIdentifier = StringHandlers.CToString(pvd.preparer_id).TrimEnd(),
ApplicationIdentifier = StringHandlers.CToString(pvd.application_data).TrimEnd()
ApplicationIdentifier = StringHandlers.CToString(pvd.application_data).TrimEnd()
};
if(pvd.creation_date[0] == '0' || pvd.creation_date[0] == 0x00) decodedVD.CreationTime = DateTime.MinValue;
else decodedVD.CreationTime = DateHandlers.Iso9660ToDateTime(pvd.creation_date);
else
decodedVD.CreationTime =
DateHandlers.Iso9660ToDateTime(pvd.creation_date);
if(pvd.modification_date[0] == '0' || pvd.modification_date[0] == 0x00)
decodedVD.HasModificationTime = false;
else
{
decodedVD.HasModificationTime = true;
decodedVD.ModificationTime = DateHandlers.Iso9660ToDateTime(pvd.modification_date);
decodedVD.ModificationTime = DateHandlers.Iso9660ToDateTime(pvd.modification_date);
}
if(pvd.expiration_date[0] == '0' || pvd.expiration_date[0] == 0x00) decodedVD.HasExpirationTime = false;
else
{
decodedVD.HasExpirationTime = true;
decodedVD.ExpirationTime = DateHandlers.Iso9660ToDateTime(pvd.expiration_date);
decodedVD.ExpirationTime = DateHandlers.Iso9660ToDateTime(pvd.expiration_date);
}
if(pvd.effective_date[0] == '0' || pvd.effective_date[0] == 0x00) decodedVD.HasEffectiveTime = false;
else
{
decodedVD.HasEffectiveTime = true;
decodedVD.EffectiveTime = DateHandlers.Iso9660ToDateTime(pvd.effective_date);
decodedVD.EffectiveTime = DateHandlers.Iso9660ToDateTime(pvd.effective_date);
}
decodedVD.Blocks = pvd.volume_space_size;
decodedVD.Blocks = pvd.volume_space_size;
decodedVD.BlockSize = pvd.logical_block_size;
return decodedVD;
@@ -85,73 +86,98 @@ namespace DiscImageChef.Filesystems.ISO9660
struct PrimaryVolumeDescriptor
{
public byte type;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)] public byte[] id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
public byte[] id;
public byte version;
// Only used in SVDs
public byte flags;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] public byte[] system_id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] public byte[] volume_id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public byte[] system_id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public byte[] volume_id;
public ulong reserved1;
public uint volume_space_size;
public uint volume_space_size_be;
public uint volume_space_size;
public uint volume_space_size_be;
// Only used in SVDs
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] public byte[] escape_sequences;
public ushort volume_set_size;
public ushort volume_set_size_be;
public ushort volume_sequence_number;
public ushort volume_sequence_number_be;
public ushort logical_block_size;
public ushort logical_block_size_be;
public uint path_table_size;
public uint path_table_size_be;
public uint type_1_path_table;
public uint opt_type_1_path_table;
public uint type_m_path_table;
public uint opt_type_m_path_table;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public byte[] escape_sequences;
public ushort volume_set_size;
public ushort volume_set_size_be;
public ushort volume_sequence_number;
public ushort volume_sequence_number_be;
public ushort logical_block_size;
public ushort logical_block_size_be;
public uint path_table_size;
public uint path_table_size_be;
public uint type_1_path_table;
public uint opt_type_1_path_table;
public uint type_m_path_table;
public uint opt_type_m_path_table;
public DirectoryRecord root_directory_record;
public byte root_directory_name;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)] public byte[] volume_set_id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)] public byte[] publisher_id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)] public byte[] preparer_id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)] public byte[] application_id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 37)] public byte[] copyright_file_id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 37)] public byte[] abstract_file_id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 37)] public byte[] bibliographic_file_id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 17)] public byte[] creation_date;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 17)] public byte[] modification_date;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 17)] public byte[] expiration_date;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 17)] public byte[] effective_date;
public byte root_directory_name;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public byte[] volume_set_id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public byte[] publisher_id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public byte[] preparer_id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
public byte[] application_id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 37)]
public byte[] copyright_file_id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 37)]
public byte[] abstract_file_id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 37)]
public byte[] bibliographic_file_id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 17)]
public byte[] creation_date;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 17)]
public byte[] modification_date;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 17)]
public byte[] expiration_date;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 17)]
public byte[] effective_date;
public byte file_structure_version;
public byte reserved2;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 512)] public byte[] application_data;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 653)] public byte[] reserved3;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 512)]
public byte[] application_data;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 653)]
public byte[] reserved3;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct BootRecord
{
public byte type;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)] public byte[] id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
public byte[] id;
public byte version;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] public byte[] system_id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] public byte[] boot_id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1977)] public byte[] boot_use;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public byte[] system_id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public byte[] boot_id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1977)]
public byte[] boot_use;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct PartitionDescriptor
{
public byte type;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)] public byte[] id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
public byte[] id;
public byte version;
public byte reserved1;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] public byte[] system_id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] public byte[] partition_id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public byte[] system_id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public byte[] partition_id;
public uint partition_location;
public uint partition_location_be;
public uint partition_size;
public uint partition_size_be;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1960)] public byte[] system_use;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1960)]
public byte[] system_use;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
@@ -163,37 +189,45 @@ namespace DiscImageChef.Filesystems.ISO9660
public uint extent_be;
public uint size;
public uint size_be;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 7)] public byte[] date;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 7)]
public byte[] date;
public FileFlags flags;
public byte file_unit_size;
public byte interleave;
public ushort volume_sequence_number;
public ushort volume_sequence_number_be;
public byte name_len;
public byte file_unit_size;
public byte interleave;
public ushort volume_sequence_number;
public ushort volume_sequence_number_be;
public byte name_len;
// Followed by name[name_len] and then system area until length arrives
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct ExtendedAttributeRecord
{
public ushort owner;
public ushort owner_be;
public ushort group;
public ushort group_be;
public ushort owner;
public ushort owner_be;
public ushort group;
public ushort group_be;
public Permissions permissions;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 17)] public byte[] creation_date;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 17)] public byte[] modification_date;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 17)] public byte[] expiration_date;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 17)] public byte[] effective_date;
public RecordFormat record_format;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 17)]
public byte[] creation_date;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 17)]
public byte[] modification_date;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 17)]
public byte[] expiration_date;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 17)]
public byte[] effective_date;
public RecordFormat record_format;
public RecordAttribute record_attributes;
public ushort record_length;
public ushort record_length_be;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] public byte[] system_id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] public byte[] system_use;
public ushort record_length;
public ushort record_length_be;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public byte[] system_id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public byte[] system_use;
public byte record_version;
public byte escape_len;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] public byte[] reserved1;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public byte[] reserved1;
public ushort app_use_len;
public ushort app_use_len_be;
}
@@ -202,9 +236,9 @@ namespace DiscImageChef.Filesystems.ISO9660
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct PathTableEntry
{
public byte name_len;
public byte xattr_len;
public uint start_lbn;
public byte name_len;
public byte xattr_len;
public uint start_lbn;
public ushort parent_dirno;
// Followed by name[name_len]
}

View File

@@ -54,7 +54,7 @@ namespace DiscImageChef.Filesystems.ISO9660
};
if(jolietvd.creation_date[0] < 0x31 || jolietvd.creation_date[0] > 0x39)
decodedVD.CreationTime = DateTime.MinValue;
decodedVD.CreationTime = DateTime.MinValue;
else decodedVD.CreationTime = DateHandlers.Iso9660ToDateTime(jolietvd.creation_date);
if(jolietvd.modification_date[0] < 0x31 || jolietvd.modification_date[0] > 0x39)
@@ -62,7 +62,7 @@ namespace DiscImageChef.Filesystems.ISO9660
else
{
decodedVD.HasModificationTime = true;
decodedVD.ModificationTime = DateHandlers.Iso9660ToDateTime(jolietvd.modification_date);
decodedVD.ModificationTime = DateHandlers.Iso9660ToDateTime(jolietvd.modification_date);
}
if(jolietvd.expiration_date[0] < 0x31 || jolietvd.expiration_date[0] > 0x39)
@@ -70,7 +70,7 @@ namespace DiscImageChef.Filesystems.ISO9660
else
{
decodedVD.HasExpirationTime = true;
decodedVD.ExpirationTime = DateHandlers.Iso9660ToDateTime(jolietvd.expiration_date);
decodedVD.ExpirationTime = DateHandlers.Iso9660ToDateTime(jolietvd.expiration_date);
}
if(jolietvd.effective_date[0] < 0x31 || jolietvd.effective_date[0] > 0x39)
@@ -78,10 +78,10 @@ namespace DiscImageChef.Filesystems.ISO9660
else
{
decodedVD.HasEffectiveTime = true;
decodedVD.EffectiveTime = DateHandlers.Iso9660ToDateTime(jolietvd.effective_date);
decodedVD.EffectiveTime = DateHandlers.Iso9660ToDateTime(jolietvd.effective_date);
}
decodedVD.Blocks = jolietvd.volume_space_size;
decodedVD.Blocks = jolietvd.volume_space_size;
decodedVD.BlockSize = jolietvd.logical_block_size;
return decodedVD;

View File

@@ -39,39 +39,39 @@ namespace DiscImageChef.Filesystems.ISO9660
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct PosixAttributes
{
public ushort signature;
public byte length;
public byte version;
public ushort signature;
public byte length;
public byte version;
public PosixMode st_mode;
public PosixMode st_mode_be;
public uint st_nlink;
public uint st_nlink_be;
public uint st_uid;
public uint st_uid_be;
public uint st_gid;
public uint st_gid_be;
public uint st_ino;
public uint st_ino_be;
public uint st_nlink;
public uint st_nlink_be;
public uint st_uid;
public uint st_uid_be;
public uint st_gid;
public uint st_gid_be;
public uint st_ino;
public uint st_ino_be;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct PosixDeviceNumber
{
public ushort signature;
public byte length;
public byte version;
public uint dev_t_high;
public uint dev_t_high_be;
public uint dev_t_low;
public uint dev_t_low_be;
public byte length;
public byte version;
public uint dev_t_high;
public uint dev_t_high_be;
public uint dev_t_low;
public uint dev_t_low_be;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct SymbolicLink
{
public ushort signature;
public byte length;
public byte version;
public ushort signature;
public byte length;
public byte version;
public SymlinkFlags flags;
// Followed by SymbolicLinkComponent (link to /bar/foo uses at least two of these structs)
}
@@ -80,16 +80,16 @@ namespace DiscImageChef.Filesystems.ISO9660
struct SymbolicLinkComponent
{
public SymlinkComponentFlags flags;
public byte length;
public byte length;
// Followed by component content
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct AlternateName
{
public ushort signature;
public byte length;
public byte version;
public ushort signature;
public byte length;
public byte version;
public AlternateNameFlags flags;
// Folowed by name, can be divided in pieces
}
@@ -98,36 +98,36 @@ namespace DiscImageChef.Filesystems.ISO9660
struct ChildLink
{
public ushort signature;
public byte length;
public byte version;
public uint child_dir_lba;
public uint child_dir_lba_be;
public byte length;
public byte version;
public uint child_dir_lba;
public uint child_dir_lba_be;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct ParentLink
{
public ushort signature;
public byte length;
public byte version;
public uint parent_dir_lba;
public uint parent_dir_lba_be;
public byte length;
public byte version;
public uint parent_dir_lba;
public uint parent_dir_lba_be;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct RelocatedDirectory
{
public ushort signature;
public byte length;
public byte version;
public byte length;
public byte version;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct Timestamps
{
public ushort signature;
public byte length;
public byte version;
public ushort signature;
public byte length;
public byte version;
public TimestampFlags flags;
// If flags indicate long format, timestamps are 17 bytes, if not, 7 bytes
// Followed by creation time if present
@@ -143,13 +143,13 @@ namespace DiscImageChef.Filesystems.ISO9660
struct SparseFile
{
public ushort signature;
public byte length;
public byte version;
public uint virtual_size_high;
public uint virtual_size_high_be;
public uint virtual_size_low;
public uint virtual_size_low_be;
public byte table_depth;
public byte length;
public byte version;
public uint virtual_size_high;
public uint virtual_size_high_be;
public uint virtual_size_low;
public uint virtual_size_low_be;
public byte table_depth;
}
}
}

View File

@@ -40,52 +40,52 @@ namespace DiscImageChef.Filesystems.ISO9660
struct ContinuationArea
{
public ushort signature;
public byte length;
public byte version;
public uint block;
public uint block_be;
public uint offset;
public uint offset_be;
public uint ca_length;
public uint ca_length_be;
public byte length;
public byte version;
public uint block;
public uint block_be;
public uint offset;
public uint offset_be;
public uint ca_length;
public uint ca_length_be;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct PaddingArea
{
public ushort signature;
public byte length;
public byte version;
public byte length;
public byte version;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct IndicatorArea
{
public ushort signature;
public byte length;
public byte version;
public byte length;
public byte version;
public ushort magic;
public byte skipped;
public byte skipped;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct TerminatorArea
{
public ushort signature;
public byte length;
public byte version;
public byte length;
public byte version;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct ReferenceArea
{
public ushort signature;
public byte length;
public byte version;
public byte id_len;
public byte des_len;
public byte src_len;
public byte ext_ver;
public byte length;
public byte version;
public byte id_len;
public byte des_len;
public byte src_len;
public byte ext_ver;
// Follows extension identifier for id_len bytes
// Follows extension descriptor for des_len bytes
// Follows extension source for src_len bytes
@@ -95,9 +95,9 @@ namespace DiscImageChef.Filesystems.ISO9660
struct SelectorArea
{
public ushort signature;
public byte length;
public byte version;
public byte sequence;
public byte length;
public byte version;
public byte sequence;
}
}
}

View File

@@ -40,12 +40,13 @@ namespace DiscImageChef.Filesystems.ISO9660
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct CdromXa
{
public ushort group;
public ushort user;
public ushort group;
public ushort user;
public XaAttributes attributes;
public ushort signature;
public byte filenumber;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)] public byte[] reserved;
public ushort signature;
public byte filenumber;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
public byte[] reserved;
}
}
}

View File

@@ -40,23 +40,23 @@ namespace DiscImageChef.Filesystems.ISO9660
struct ZisofsHeader
{
public ulong magic;
public uint uncomp_len;
public uint uncomp_len_be;
public byte header_size; // Shifted >> 2
public byte block_size_log; // log2(block_size)
public uint uncomp_len;
public uint uncomp_len_be;
public byte header_size; // Shifted >> 2
public byte block_size_log; // log2(block_size)
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct ZisofsEntry
{
public ushort signature;
public byte length;
public byte version;
public byte length;
public byte version;
public ushort alogirhtm;
public byte header_size; // Shifted >> 2
public byte block_size_log; // log2(block_size)
public uint uncomp_len;
public uint uncomp_len_be;
public byte header_size; // Shifted >> 2
public byte block_size_log; // log2(block_size)
public uint uncomp_len;
public uint uncomp_len_be;
}
}
}

View File

@@ -42,12 +42,12 @@ namespace DiscImageChef.Filesystems
public class JFS : IFilesystem
{
const uint JFS_BOOT_BLOCKS_SIZE = 0x8000;
const uint JFS_MAGIC = 0x3153464A;
const uint JFS_MAGIC = 0x3153464A;
public FileSystemType XmlFsType { get; private set; }
public Encoding Encoding { get; private set; }
public string Name => "JFS Plugin";
public Guid Id => new Guid("D3BE2A41-8F28-4055-94DC-BB6C72A0E9C4");
public Encoding Encoding { get; private set; }
public string Name => "JFS Plugin";
public Guid Id => new Guid("D3BE2A41-8F28-4055-94DC-BB6C72A0E9C4");
public bool Identify(IMediaImage imagePlugin, Partition partition)
{
@@ -58,7 +58,7 @@ namespace DiscImageChef.Filesystems
if(sector.Length < 512) return false;
JfsSuperBlock jfsSb = new JfsSuperBlock();
IntPtr sbPtr = Marshal.AllocHGlobal(Marshal.SizeOf(jfsSb));
IntPtr sbPtr = Marshal.AllocHGlobal(Marshal.SizeOf(jfsSb));
Marshal.Copy(sector, 0, sbPtr, Marshal.SizeOf(jfsSb));
jfsSb = (JfsSuperBlock)Marshal.PtrToStructure(sbPtr, typeof(JfsSuperBlock));
Marshal.FreeHGlobal(sbPtr);
@@ -67,17 +67,17 @@ namespace DiscImageChef.Filesystems
}
public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
Encoding encoding)
Encoding encoding)
{
Encoding = encoding ?? Encoding.GetEncoding("iso-8859-15");
Encoding = encoding ?? Encoding.GetEncoding("iso-8859-15");
information = "";
StringBuilder sb = new StringBuilder();
uint bootSectors = JFS_BOOT_BLOCKS_SIZE / imagePlugin.Info.SectorSize;
byte[] sector = imagePlugin.ReadSector(partition.Start + bootSectors);
StringBuilder sb = new StringBuilder();
uint bootSectors = JFS_BOOT_BLOCKS_SIZE / imagePlugin.Info.SectorSize;
byte[] sector = imagePlugin.ReadSector(partition.Start + bootSectors);
if(sector.Length < 512) return;
JfsSuperBlock jfsSb = new JfsSuperBlock();
IntPtr sbPtr = Marshal.AllocHGlobal(Marshal.SizeOf(jfsSb));
IntPtr sbPtr = Marshal.AllocHGlobal(Marshal.SizeOf(jfsSb));
Marshal.Copy(sector, 0, sbPtr, Marshal.SizeOf(jfsSb));
jfsSb = (JfsSuperBlock)Marshal.PtrToStructure(sbPtr, typeof(JfsSuperBlock));
Marshal.FreeHGlobal(sbPtr);
@@ -123,13 +123,14 @@ namespace DiscImageChef.Filesystems
XmlFsType = new FileSystemType
{
Type = "JFS filesystem",
Clusters = (long)jfsSb.s_size,
ClusterSize = (int)jfsSb.s_bsize,
Bootable = true,
VolumeName = Encoding.GetString(jfsSb.s_version == 1 ? jfsSb.s_fpack : jfsSb.s_label),
Type = "JFS filesystem",
Clusters = (long)jfsSb.s_size,
ClusterSize = (int)jfsSb.s_bsize,
Bootable = true,
VolumeName = Encoding.GetString(jfsSb.s_version == 1 ? jfsSb.s_fpack : jfsSb.s_label),
VolumeSerial = $"{jfsSb.s_uuid}",
ModificationDate = DateHandlers.UnixUnsignedToDateTime(jfsSb.s_time.tv_sec, jfsSb.s_time.tv_nsec),
ModificationDate =
DateHandlers.UnixUnsignedToDateTime(jfsSb.s_time.tv_sec, jfsSb.s_time.tv_nsec),
ModificationDateSpecified = true
};
if(jfsSb.s_state != 0) XmlFsType.Dirty = true;
@@ -140,38 +141,38 @@ namespace DiscImageChef.Filesystems
[Flags]
enum JfsFlags : uint
{
Unicode = 0x00000001,
RemountRO = 0x00000002,
Continue = 0x00000004,
Panic = 0x00000008,
UserQuota = 0x00000010,
GroupQuota = 0x00000020,
NoJournal = 0x00000040,
Discard = 0x00000080,
GroupCommit = 0x00000100,
LazyCommit = 0x00000200,
Temporary = 0x00000400,
InlineLog = 0x00000800,
Unicode = 0x00000001,
RemountRO = 0x00000002,
Continue = 0x00000004,
Panic = 0x00000008,
UserQuota = 0x00000010,
GroupQuota = 0x00000020,
NoJournal = 0x00000040,
Discard = 0x00000080,
GroupCommit = 0x00000100,
LazyCommit = 0x00000200,
Temporary = 0x00000400,
InlineLog = 0x00000800,
InlineMoving = 0x00001000,
BadSAIT = 0x00010000,
Sparse = 0x00020000,
DASDEnabled = 0x00040000,
DASDPrime = 0x00080000,
SwapBytes = 0x00100000,
DirIndex = 0x00200000,
Linux = 0x10000000,
DFS = 0x20000000,
OS2 = 0x40000000,
AIX = 0x80000000
BadSAIT = 0x00010000,
Sparse = 0x00020000,
DASDEnabled = 0x00040000,
DASDPrime = 0x00080000,
SwapBytes = 0x00100000,
DirIndex = 0x00200000,
Linux = 0x10000000,
DFS = 0x20000000,
OS2 = 0x40000000,
AIX = 0x80000000
}
[Flags]
enum JfsState : uint
{
Clean = 0,
Mounted = 1,
Dirty = 2,
Logredo = 4,
Clean = 0,
Mounted = 1,
Dirty = 2,
Logredo = 4,
Extendfs = 8
}
@@ -195,34 +196,36 @@ namespace DiscImageChef.Filesystems
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct JfsSuperBlock
{
public uint s_magic;
public uint s_version;
public ulong s_size;
public uint s_bsize;
public ushort s_l2bsize;
public ushort s_l2bfactor;
public uint s_pbsize;
public ushort s_l1pbsize;
public ushort pad;
public uint s_agsize;
public JfsFlags s_flags;
public JfsState s_state;
public uint s_compress;
public JfsExtent s_ait2;
public JfsExtent s_aim2;
public uint s_logdev;
public uint s_logserial;
public JfsExtent s_logpxd;
public JfsExtent s_fsckpxd;
public uint s_magic;
public uint s_version;
public ulong s_size;
public uint s_bsize;
public ushort s_l2bsize;
public ushort s_l2bfactor;
public uint s_pbsize;
public ushort s_l1pbsize;
public ushort pad;
public uint s_agsize;
public JfsFlags s_flags;
public JfsState s_state;
public uint s_compress;
public JfsExtent s_ait2;
public JfsExtent s_aim2;
public uint s_logdev;
public uint s_logserial;
public JfsExtent s_logpxd;
public JfsExtent s_fsckpxd;
public JfsTimeStruct s_time;
public uint s_fsckloglen;
public sbyte s_fscklog;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 11)] public byte[] s_fpack;
public ulong s_xsize;
public uint s_fsckloglen;
public sbyte s_fscklog;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 11)]
public byte[] s_fpack;
public ulong s_xsize;
public JfsExtent s_xfsckpxd;
public JfsExtent s_xlogpxd;
public Guid s_uuid;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public byte[] s_label;
public Guid s_uuid;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[] s_label;
public Guid s_loguuid;
}
}

View File

@@ -46,31 +46,31 @@ namespace DiscImageChef.Filesystems
const uint LIF_MAGIC = 0x8000;
public FileSystemType XmlFsType { get; private set; }
public Encoding Encoding { get; private set; }
public string Name => "HP Logical Interchange Format Plugin";
public Guid Id => new Guid("41535647-77A5-477B-9206-DA727ACDC704");
public Encoding Encoding { get; private set; }
public string Name => "HP Logical Interchange Format Plugin";
public Guid Id => new Guid("41535647-77A5-477B-9206-DA727ACDC704");
public bool Identify(IMediaImage imagePlugin, Partition partition)
{
if(imagePlugin.Info.SectorSize < 256) return false;
byte[] sector = imagePlugin.ReadSector(partition.Start);
LifSystemBlock lifSb = BigEndianMarshal.ByteArrayToStructureBigEndian<LifSystemBlock>(sector);
byte[] sector = imagePlugin.ReadSector(partition.Start);
LifSystemBlock lifSb = BigEndianMarshal.ByteArrayToStructureBigEndian<LifSystemBlock>(sector);
DicConsole.DebugWriteLine("LIF plugin", "magic 0x{0:X8} (expected 0x{1:X8})", lifSb.magic, LIF_MAGIC);
return lifSb.magic == LIF_MAGIC;
}
public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
Encoding encoding)
Encoding encoding)
{
Encoding = encoding ?? Encoding.GetEncoding("iso-8859-15");
Encoding = encoding ?? Encoding.GetEncoding("iso-8859-15");
information = "";
if(imagePlugin.Info.SectorSize < 256) return;
byte[] sector = imagePlugin.ReadSector(partition.Start);
LifSystemBlock lifSb = BigEndianMarshal.ByteArrayToStructureBigEndian<LifSystemBlock>(sector);
byte[] sector = imagePlugin.ReadSector(partition.Start);
LifSystemBlock lifSb = BigEndianMarshal.ByteArrayToStructureBigEndian<LifSystemBlock>(sector);
if(lifSb.magic != LIF_MAGIC) return;
@@ -92,12 +92,12 @@ namespace DiscImageChef.Filesystems
XmlFsType = new FileSystemType
{
Type = "HP Logical Interchange Format",
ClusterSize = 256,
Clusters = (long)(partition.Size / 256),
CreationDate = DateHandlers.LifToDateTime(lifSb.creationDate),
Type = "HP Logical Interchange Format",
ClusterSize = 256,
Clusters = (long)(partition.Size / 256),
CreationDate = DateHandlers.LifToDateTime(lifSb.creationDate),
CreationDateSpecified = true,
VolumeName = StringHandlers.CToString(lifSb.volumeLabel, Encoding)
VolumeName = StringHandlers.CToString(lifSb.volumeLabel, Encoding)
};
}
@@ -105,17 +105,19 @@ namespace DiscImageChef.Filesystems
struct LifSystemBlock
{
public ushort magic;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)] public byte[] volumeLabel;
public uint directoryStart;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
public byte[] volumeLabel;
public uint directoryStart;
public ushort lifId;
public ushort unused;
public uint directorySize;
public uint directorySize;
public ushort lifVersion;
public ushort unused2;
public uint tracks;
public uint heads;
public uint sectors;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)] public byte[] creationDate;
public uint tracks;
public uint heads;
public uint sectors;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
public byte[] creationDate;
}
}
}

View File

@@ -81,7 +81,7 @@ namespace DiscImageChef.Filesystems.LisaFS
const ushort FILEID_SRECORD = 0x0003;
/// <summary>The root catalog</summary>
const ushort FILEID_CATALOG = 0x0004;
const short FILEID_BOOT_SIGNED = -21846;
const short FILEID_BOOT_SIGNED = -21846;
const short FILEID_LOADER_SIGNED = -17477;
/// <summary>
/// A file that has been erased

View File

@@ -114,7 +114,7 @@ namespace DiscImageChef.Filesystems.LisaFS
Errno error = ReadFile((short)FILEID_CATALOG, out byte[] buf);
if(error != Errno.NoError) return error;
int offset = 0;
int offset = 0;
List<CatalogEntryV2> catalogV2 = new List<CatalogEntryV2>();
// For each entry on the catalog
@@ -123,12 +123,12 @@ namespace DiscImageChef.Filesystems.LisaFS
CatalogEntryV2 entV2 = new CatalogEntryV2
{
filenameLen = buf[offset],
filename = new byte[E_NAME],
unknown1 = buf[offset + 0x21],
fileType = buf[offset + 0x22],
unknown2 = buf[offset + 0x23],
fileID = BigEndianBitConverter.ToInt16(buf, offset + 0x24),
unknown3 = new byte[16]
filename = new byte[E_NAME],
unknown1 = buf[offset + 0x21],
fileType = buf[offset + 0x22],
unknown2 = buf[offset + 0x23],
fileID = BigEndianBitConverter.ToInt16(buf, offset + 0x24),
unknown3 = new byte[16]
};
Array.Copy(buf, offset + 0x01, entV2.filename, 0, E_NAME);
Array.Copy(buf, offset + 0x26, entV2.unknown3, 0, 16);
@@ -148,12 +148,12 @@ namespace DiscImageChef.Filesystems.LisaFS
CatalogEntry entV3 = new CatalogEntry
{
fileID = entV2.fileID,
fileID = entV2.fileID,
filename = new byte[32],
fileType = entV2.fileType,
length = (int)srecords[entV2.fileID].filesize,
dtc = ext.dtc,
dtm = ext.dtm
length = (int)srecords[entV2.fileID].filesize,
dtc = ext.dtc,
dtm = ext.dtm
};
Array.Copy(entV2.filename, 0, entV3.filename, 0, entV2.filenameLen);
@@ -192,7 +192,7 @@ namespace DiscImageChef.Filesystems.LisaFS
if(prevTag.FileId != FILEID_CATALOG) return Errno.InvalidArgument;
firstCatalogBlock = device.ReadSectors(prevCatalogPointer + mddf.mddf_block + volumePrefix, 4);
firstCatalogBlock = device.ReadSectors(prevCatalogPointer + mddf.mddf_block + volumePrefix, 4);
prevCatalogPointer = BigEndianBitConverter.ToUInt32(firstCatalogBlock, 0x7F6);
}
@@ -222,7 +222,8 @@ namespace DiscImageChef.Filesystems.LisaFS
// Traverse all entries
while(offset + 64 <= buf.Length)
// Catalog block header
if(buf[offset + 0x24] == 0x08) offset += 78;
if(buf[offset + 0x24] == 0x08)
offset += 78;
// Maybe just garbage? Found in more than 1 disk
else if(buf[offset + 0x24] == 0x7C) offset += 50;
// Apparently reserved to indicate end of catalog?
@@ -232,21 +233,21 @@ namespace DiscImageChef.Filesystems.LisaFS
{
CatalogEntry entry = new CatalogEntry
{
marker = buf[offset],
parentID = BigEndianBitConverter.ToUInt16(buf, offset + 0x01),
filename = new byte[E_NAME],
terminator = buf[offset + 0x23],
fileType = buf[offset + 0x24],
unknown = buf[offset + 0x25],
fileID = BigEndianBitConverter.ToInt16(buf, offset + 0x26),
dtc = BigEndianBitConverter.ToUInt32(buf, offset + 0x28),
dtm = BigEndianBitConverter.ToUInt32(buf, offset + 0x2C),
length = BigEndianBitConverter.ToInt32(buf, offset + 0x30),
wasted = BigEndianBitConverter.ToInt32(buf, offset + 0x34),
tail = new byte[8]
marker = buf[offset],
parentID = BigEndianBitConverter.ToUInt16(buf, offset + 0x01),
filename = new byte[E_NAME],
terminator = buf[offset + 0x23],
fileType = buf[offset + 0x24],
unknown = buf[offset + 0x25],
fileID = BigEndianBitConverter.ToInt16(buf, offset + 0x26),
dtc = BigEndianBitConverter.ToUInt32(buf, offset + 0x28),
dtm = BigEndianBitConverter.ToUInt32(buf, offset + 0x2C),
length = BigEndianBitConverter.ToInt32(buf, offset + 0x30),
wasted = BigEndianBitConverter.ToInt32(buf, offset + 0x34),
tail = new byte[8]
};
Array.Copy(buf, offset + 0x03, entry.filename, 0, E_NAME);
Array.Copy(buf, offset + 0x38, entry.tail, 0, 8);
Array.Copy(buf, offset + 0x38, entry.tail, 0, 8);
if(ReadExtentsFile(entry.fileID, out _) == Errno.NoError)
if(!fileSizeCache.ContainsKey(entry.fileID))
@@ -262,18 +263,18 @@ namespace DiscImageChef.Filesystems.LisaFS
{
CatalogEntry entry = new CatalogEntry
{
marker = buf[offset],
parentID = BigEndianBitConverter.ToUInt16(buf, offset + 0x01),
filename = new byte[E_NAME],
terminator = buf[offset + 0x23],
fileType = buf[offset + 0x24],
unknown = buf[offset + 0x25],
fileID = BigEndianBitConverter.ToInt16(buf, offset + 0x26),
dtc = BigEndianBitConverter.ToUInt32(buf, offset + 0x28),
dtm = BigEndianBitConverter.ToUInt32(buf, offset + 0x2C),
length = 0,
wasted = 0,
tail = null
marker = buf[offset],
parentID = BigEndianBitConverter.ToUInt16(buf, offset + 0x01),
filename = new byte[E_NAME],
terminator = buf[offset + 0x23],
fileType = buf[offset + 0x24],
unknown = buf[offset + 0x25],
fileID = BigEndianBitConverter.ToInt16(buf, offset + 0x26),
dtc = BigEndianBitConverter.ToUInt32(buf, offset + 0x28),
dtm = BigEndianBitConverter.ToUInt32(buf, offset + 0x2C),
length = 0,
wasted = 0,
tail = null
};
Array.Copy(buf, offset + 0x03, entry.filename, 0, E_NAME);
@@ -299,15 +300,15 @@ namespace DiscImageChef.Filesystems.LisaFS
stat = new FileEntryInfo
{
Attributes = new FileAttributes(),
Inode = FILEID_CATALOG,
Mode = 0x16D,
Links = 0,
UID = 0,
GID = 0,
DeviceNo = 0,
Length = 0,
BlockSize = mddf.datasize,
Blocks = 0
Inode = FILEID_CATALOG,
Mode = 0x16D,
Links = 0,
UID = 0,
GID = 0,
DeviceNo = 0,
Length = 0,
BlockSize = mddf.datasize,
Blocks = 0
};
directoryDtcCache.TryGetValue(dirId, out DateTime tmp);

View File

@@ -88,7 +88,7 @@ namespace DiscImageChef.Filesystems.LisaFS
DecodeTag(device.ReadSectorTag(i, SectorTagType.AppleSectorTag), out extTag);
if(extTag.FileId != fileId * -1) continue;
ptr = i;
ptr = i;
found = true;
break;
}
@@ -106,36 +106,36 @@ namespace DiscImageChef.Filesystems.LisaFS
if(sector[0] >= 32 || sector[0] == 0) return Errno.InvalidArgument;
file.filenameLen = sector[0];
file.filename = new byte[file.filenameLen];
file.filename = new byte[file.filenameLen];
Array.Copy(sector, 0x01, file.filename, 0, file.filenameLen);
file.unknown1 = BigEndianBitConverter.ToUInt16(sector, 0x20);
file.file_uid = BigEndianBitConverter.ToUInt64(sector, 0x22);
file.unknown2 = sector[0x2A];
file.etype = sector[0x2B];
file.ftype = (FileType)sector[0x2C];
file.unknown3 = sector[0x2D];
file.dtc = BigEndianBitConverter.ToUInt32(sector, 0x2E);
file.dta = BigEndianBitConverter.ToUInt32(sector, 0x32);
file.dtm = BigEndianBitConverter.ToUInt32(sector, 0x36);
file.dtb = BigEndianBitConverter.ToUInt32(sector, 0x3A);
file.dts = BigEndianBitConverter.ToUInt32(sector, 0x3E);
file.serial = BigEndianBitConverter.ToUInt32(sector, 0x42);
file.unknown4 = sector[0x46];
file.locked = sector[0x47];
file.protect = sector[0x48];
file.master = sector[0x49];
file.unknown1 = BigEndianBitConverter.ToUInt16(sector, 0x20);
file.file_uid = BigEndianBitConverter.ToUInt64(sector, 0x22);
file.unknown2 = sector[0x2A];
file.etype = sector[0x2B];
file.ftype = (FileType)sector[0x2C];
file.unknown3 = sector[0x2D];
file.dtc = BigEndianBitConverter.ToUInt32(sector, 0x2E);
file.dta = BigEndianBitConverter.ToUInt32(sector, 0x32);
file.dtm = BigEndianBitConverter.ToUInt32(sector, 0x36);
file.dtb = BigEndianBitConverter.ToUInt32(sector, 0x3A);
file.dts = BigEndianBitConverter.ToUInt32(sector, 0x3E);
file.serial = BigEndianBitConverter.ToUInt32(sector, 0x42);
file.unknown4 = sector[0x46];
file.locked = sector[0x47];
file.protect = sector[0x48];
file.master = sector[0x49];
file.scavenged = sector[0x4A];
file.closed = sector[0x4B];
file.open = sector[0x4C];
file.unknown5 = new byte[11];
file.closed = sector[0x4B];
file.open = sector[0x4C];
file.unknown5 = new byte[11];
Array.Copy(sector, 0x4D, file.unknown5, 0, 11);
file.release = BigEndianBitConverter.ToUInt16(sector, 0x58);
file.build = BigEndianBitConverter.ToUInt16(sector, 0x5A);
file.compatibility = BigEndianBitConverter.ToUInt16(sector, 0x5C);
file.revision = BigEndianBitConverter.ToUInt16(sector, 0x5E);
file.unknown6 = BigEndianBitConverter.ToUInt16(sector, 0x60);
file.release = BigEndianBitConverter.ToUInt16(sector, 0x58);
file.build = BigEndianBitConverter.ToUInt16(sector, 0x5A);
file.compatibility = BigEndianBitConverter.ToUInt16(sector, 0x5C);
file.revision = BigEndianBitConverter.ToUInt16(sector, 0x5E);
file.unknown6 = BigEndianBitConverter.ToUInt16(sector, 0x60);
file.password_valid = sector[0x62];
file.password = new byte[8];
file.password = new byte[8];
Array.Copy(sector, 0x63, file.password, 0, 8);
file.unknown7 = new byte[3];
Array.Copy(sector, 0x6B, file.unknown7, 0, 3);
@@ -143,7 +143,7 @@ namespace DiscImageChef.Filesystems.LisaFS
file.unknown8 = new byte[16];
Array.Copy(sector, 0x70, file.unknown8, 0, 16);
file.unknown10 = BigEndianBitConverter.ToInt16(sector, 0x17E);
file.LisaInfo = new byte[128];
file.LisaInfo = new byte[128];
Array.Copy(sector, 0x180, file.LisaInfo, 0, 128);
int extentsCount = 0;
@@ -151,13 +151,13 @@ namespace DiscImageChef.Filesystems.LisaFS
if(mddf.fsversion == LISA_V1)
{
file.length = BigEndianBitConverter.ToInt32(sector, 0x200);
file.length = BigEndianBitConverter.ToInt32(sector, 0x200);
file.unknown9 = BigEndianBitConverter.ToInt32(sector, 0x204);
extentsOffset = 0x208;
}
else
{
file.length = BigEndianBitConverter.ToInt32(sector, 0x80);
file.length = BigEndianBitConverter.ToInt32(sector, 0x80);
file.unknown9 = BigEndianBitConverter.ToInt32(sector, 0x84);
extentsOffset = 0x88;
}
@@ -174,7 +174,7 @@ namespace DiscImageChef.Filesystems.LisaFS
for(int j = 0; j < extentsCount; j++)
file.extents[j] = new Extent
{
start = BigEndianBitConverter.ToInt32(sector, extentsOffset + j * 6),
start = BigEndianBitConverter.ToInt32(sector, extentsOffset + j * 6),
length = BigEndianBitConverter.ToInt16(sector, extentsOffset + j * 6 + 4)
};
@@ -187,35 +187,41 @@ namespace DiscImageChef.Filesystems.LisaFS
DicConsole.DebugWriteLine("LisaFS plugin", "ExtentFile[{0}].filenameLen = {1}", fileId, file.filenameLen);
DicConsole.DebugWriteLine("LisaFS plugin", "ExtentFile[{0}].filename = {1}", fileId,
StringHandlers.CToString(file.filename, Encoding));
DicConsole.DebugWriteLine("LisaFS plugin", "ExtentFile[{0}].unknown1 = 0x{1:X4}", fileId, file.unknown1);
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}].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}].locked = {1}", fileId, file.locked > 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}].closed = {1}", fileId, file.closed > 0);
DicConsole.DebugWriteLine("LisaFS plugin", "ExtentFile[{0}].open = {1}", fileId, file.open > 0);
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}].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}].locked = {1}", fileId,
file.locked > 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}].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]);
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}].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}].revision = {1}", fileId, file.revision);
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);
@@ -231,7 +237,7 @@ namespace DiscImageChef.Filesystems.LisaFS
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}].length = {1}", fileId, file.length);
DicConsole.DebugWriteLine("LisaFS plugin", "ExtentFile[{0}].unknown9 = 0x{1:X8}", fileId, file.unknown9);
for(int ext = 0; ext < file.extents.Length; ext++)
{
@@ -265,9 +271,9 @@ namespace DiscImageChef.Filesystems.LisaFS
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)
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

@@ -113,8 +113,8 @@ namespace DiscImageChef.Filesystems.LisaFS
{
if(!debug) return Errno.NoSuchFile;
attributes = new FileAttributes();
attributes = FileAttributes.System;
attributes = new FileAttributes();
attributes = FileAttributes.System;
attributes |= FileAttributes.Hidden;
attributes |= FileAttributes.File;
@@ -145,8 +145,8 @@ namespace DiscImageChef.Filesystems.LisaFS
break;
}
if(extFile.protect > 0) attributes |= FileAttributes.Immutable;
if(extFile.locked > 0) attributes |= FileAttributes.ReadOnly;
if(extFile.protect > 0) attributes |= FileAttributes.Immutable;
if(extFile.locked > 0) attributes |= FileAttributes.ReadOnly;
if(extFile.password_valid > 0) attributes |= FileAttributes.Password;
return Errno.NoError;
@@ -163,7 +163,8 @@ namespace DiscImageChef.Filesystems.LisaFS
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 != FILEID_BOOT_SIGNED && fileId != FILEID_LOADER_SIGNED)
return Errno.InvalidArgument;
if(systemFileCache.TryGetValue(fileId, out buf) && !tags) return Errno.NoError;
@@ -223,11 +224,12 @@ namespace DiscImageChef.Filesystems.LisaFS
if(!mounted) return Errno.AccessDenied;
Errno error;
Errno error;
ExtentFile file;
if(fileId <= 4)
if(!debug || fileId == 0) return Errno.NoSuchFile;
if(!debug || fileId == 0)
return Errno.NoSuchFile;
else
{
stat = new FileEntryInfo {Attributes = new FileAttributes()};
@@ -240,20 +242,20 @@ namespace DiscImageChef.Filesystems.LisaFS
error = ReadExtentsFile((short)(fileId * -1), out file);
if(error != Errno.NoError) return error;
stat.CreationTime = DateHandlers.LisaToDateTime(file.dtc);
stat.AccessTime = DateHandlers.LisaToDateTime(file.dta);
stat.BackupTime = DateHandlers.LisaToDateTime(file.dtb);
stat.CreationTime = DateHandlers.LisaToDateTime(file.dtc);
stat.AccessTime = DateHandlers.LisaToDateTime(file.dta);
stat.BackupTime = DateHandlers.LisaToDateTime(file.dtb);
stat.LastWriteTime = DateHandlers.LisaToDateTime(file.dtm);
stat.Inode = (ulong)fileId;
stat.Mode = 0x124;
stat.Links = 0;
stat.UID = 0;
stat.GID = 0;
stat.DeviceNo = 0;
stat.Length = mddf.datasize;
stat.Inode = (ulong)fileId;
stat.Mode = 0x124;
stat.Links = 0;
stat.UID = 0;
stat.GID = 0;
stat.DeviceNo = 0;
stat.Length = mddf.datasize;
stat.BlockSize = mddf.datasize;
stat.Blocks = 1;
stat.Blocks = 1;
}
else
{
@@ -264,42 +266,42 @@ namespace DiscImageChef.Filesystems.LisaFS
stat.BackupTime = mddf.dtvb;
stat.Inode = (ulong)fileId;
stat.Mode = 0x124;
stat.Links = 0;
stat.UID = 0;
stat.GID = 0;
stat.DeviceNo = 0;
stat.Length = buf.Length;
stat.Inode = (ulong)fileId;
stat.Mode = 0x124;
stat.Links = 0;
stat.UID = 0;
stat.GID = 0;
stat.DeviceNo = 0;
stat.Length = buf.Length;
stat.BlockSize = mddf.datasize;
stat.Blocks = buf.Length / mddf.datasize;
stat.Blocks = buf.Length / mddf.datasize;
}
return Errno.NoError;
}
stat = new FileEntryInfo {Attributes = new FileAttributes()};
stat = new FileEntryInfo {Attributes = new FileAttributes()};
error = GetAttributes(fileId, out stat.Attributes);
if(error != Errno.NoError) return error;
error = ReadExtentsFile(fileId, out file);
if(error != Errno.NoError) return error;
stat.CreationTime = DateHandlers.LisaToDateTime(file.dtc);
stat.AccessTime = DateHandlers.LisaToDateTime(file.dta);
stat.BackupTime = DateHandlers.LisaToDateTime(file.dtb);
stat.CreationTime = DateHandlers.LisaToDateTime(file.dtc);
stat.AccessTime = DateHandlers.LisaToDateTime(file.dta);
stat.BackupTime = DateHandlers.LisaToDateTime(file.dtb);
stat.LastWriteTime = DateHandlers.LisaToDateTime(file.dtm);
stat.Inode = (ulong)fileId;
stat.Mode = 0x1B6;
stat.Links = 1;
stat.UID = 0;
stat.GID = 0;
stat.Inode = (ulong)fileId;
stat.Mode = 0x1B6;
stat.Links = 1;
stat.UID = 0;
stat.GID = 0;
stat.DeviceNo = 0;
if(!fileSizeCache.TryGetValue(fileId, out int len)) stat.Length = srecords[fileId].filesize;
else stat.Length = len;
else stat.Length = len;
stat.BlockSize = mddf.datasize;
stat.Blocks = file.length;
stat.Blocks = file.length;
return Errno.NoError;
}
@@ -326,7 +328,7 @@ namespace DiscImageChef.Filesystems.LisaFS
int sectorSize;
if(tags) sectorSize = devTagSize;
else sectorSize = (int)device.Info.SectorSize;
else sectorSize = (int)device.Info.SectorSize;
byte[] temp = new byte[file.length * sectorSize];
@@ -349,7 +351,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(realSize > temp.Length)
DicConsole.ErrorWriteLine("File {0} gets truncated.", fileId);
buf = temp;
fileCache.Add(fileId, buf);
@@ -362,7 +365,7 @@ namespace DiscImageChef.Filesystems.LisaFS
Errno LookupFileId(string path, out short fileId, out bool isDir)
{
fileId = 0;
isDir = false;
isDir = false;
if(!mounted) return Errno.AccessDenied;
@@ -371,7 +374,7 @@ namespace DiscImageChef.Filesystems.LisaFS
if(pathElements.Length == 0)
{
fileId = DIRID_ROOT;
isDir = true;
isDir = true;
return Errno.NoError;
}
@@ -413,7 +416,7 @@ namespace DiscImageChef.Filesystems.LisaFS
if(string.Compare(pathElements[0], "$", StringComparison.InvariantCulture) == 0)
{
fileId = DIRID_ROOT;
isDir = true;
isDir = true;
return Errno.NoError;
}
}
@@ -428,10 +431,11 @@ namespace DiscImageChef.Filesystems.LisaFS
// LisaOS is case insensitive
if(string.Compare(wantedFilename, filename, StringComparison.InvariantCultureIgnoreCase) != 0 ||
entry.parentID != fileId) continue;
entry.parentID !=
fileId) continue;
fileId = entry.fileID;
isDir = entry.fileType == 0x01;
isDir = entry.fileType == 0x01;
// Not last path element, and it's not a directory
if(lvl != pathElements.Length - 1 && !isDir) return Errno.NotDirectory;

View File

@@ -75,24 +75,26 @@ namespace DiscImageChef.Filesystems.LisaFS
byte[] sector = imagePlugin.ReadSector((ulong)i);
MDDF infoMddf = new MDDF
{
mddf_block = BigEndianBitConverter.ToUInt32(sector, 0x6C),
volsize_minus_one = BigEndianBitConverter.ToUInt32(sector, 0x70),
mddf_block = BigEndianBitConverter.ToUInt32(sector, 0x6C),
volsize_minus_one = BigEndianBitConverter.ToUInt32(sector, 0x70),
volsize_minus_mddf_minus_one = BigEndianBitConverter.ToUInt32(sector, 0x74),
vol_size = BigEndianBitConverter.ToUInt32(sector, 0x78),
blocksize = BigEndianBitConverter.ToUInt16(sector, 0x7C),
datasize = BigEndianBitConverter.ToUInt16(sector, 0x7E)
vol_size = BigEndianBitConverter.ToUInt32(sector, 0x78),
blocksize = BigEndianBitConverter.ToUInt16(sector, 0x7C),
datasize = BigEndianBitConverter.ToUInt16(sector, 0x7E)
};
DicConsole.DebugWriteLine("LisaFS plugin", "Current sector = {0}", i);
DicConsole.DebugWriteLine("LisaFS plugin", "mddf.mddf_block = {0}", infoMddf.mddf_block);
DicConsole.DebugWriteLine("LisaFS plugin", "Disk size = {0} sectors", imagePlugin.Info.Sectors);
DicConsole.DebugWriteLine("LisaFS plugin", "Current sector = {0}", i);
DicConsole.DebugWriteLine("LisaFS plugin", "mddf.mddf_block = {0}", infoMddf.mddf_block);
DicConsole.DebugWriteLine("LisaFS plugin", "Disk size = {0} sectors", imagePlugin.Info.Sectors);
DicConsole.DebugWriteLine("LisaFS plugin", "mddf.vol_size = {0} sectors", infoMddf.vol_size);
DicConsole.DebugWriteLine("LisaFS plugin", "mddf.vol_size - 1 = {0}", infoMddf.volsize_minus_one);
DicConsole.DebugWriteLine("LisaFS plugin", "mddf.vol_size - 1 = {0}",
infoMddf.volsize_minus_one);
DicConsole.DebugWriteLine("LisaFS plugin", "mddf.vol_size - mddf.mddf_block -1 = {0}",
infoMddf.volsize_minus_mddf_minus_one);
DicConsole.DebugWriteLine("LisaFS plugin", "Disk sector = {0} bytes", imagePlugin.Info.SectorSize);
DicConsole.DebugWriteLine("LisaFS plugin", "Disk sector = {0} bytes",
imagePlugin.Info.SectorSize);
DicConsole.DebugWriteLine("LisaFS plugin", "mddf.blocksize = {0} bytes", infoMddf.blocksize);
DicConsole.DebugWriteLine("LisaFS plugin", "mddf.datasize = {0} bytes", infoMddf.datasize);
DicConsole.DebugWriteLine("LisaFS plugin", "mddf.datasize = {0} bytes", infoMddf.datasize);
if(infoMddf.mddf_block != i - beforeMddf) return false;
@@ -119,9 +121,9 @@ namespace DiscImageChef.Filesystems.LisaFS
}
public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
Encoding encoding)
Encoding encoding)
{
Encoding = new LisaRoman();
Encoding = new LisaRoman();
information = "";
StringBuilder sb = new StringBuilder();
@@ -151,97 +153,97 @@ namespace DiscImageChef.Filesystems.LisaFS
if(searchTag.FileId != FILEID_MDDF) continue;
byte[] sector = imagePlugin.ReadSector((ulong)i);
MDDF infoMddf = new MDDF();
byte[] pString = new byte[33];
byte[] sector = imagePlugin.ReadSector((ulong)i);
MDDF infoMddf = new MDDF();
byte[] pString = new byte[33];
infoMddf.fsversion = BigEndianBitConverter.ToUInt16(sector, 0x00);
infoMddf.volid = BigEndianBitConverter.ToUInt64(sector, 0x02);
infoMddf.volnum = BigEndianBitConverter.ToUInt16(sector, 0x0A);
infoMddf.volid = BigEndianBitConverter.ToUInt64(sector, 0x02);
infoMddf.volnum = BigEndianBitConverter.ToUInt16(sector, 0x0A);
Array.Copy(sector, 0x0C, pString, 0, 33);
infoMddf.volname = StringHandlers.PascalToString(pString, Encoding);
infoMddf.volname = StringHandlers.PascalToString(pString, Encoding);
infoMddf.unknown1 = sector[0x2D];
Array.Copy(sector, 0x2E, pString, 0, 33);
// Prevent garbage
infoMddf.password = pString[0] <= 32 ? StringHandlers.PascalToString(pString, Encoding) : "";
infoMddf.unknown2 = sector[0x4F];
infoMddf.machine_id = BigEndianBitConverter.ToUInt32(sector, 0x50);
infoMddf.password = pString[0] <= 32 ? StringHandlers.PascalToString(pString, Encoding) : "";
infoMddf.unknown2 = sector[0x4F];
infoMddf.machine_id = BigEndianBitConverter.ToUInt32(sector, 0x50);
infoMddf.master_copy_id = BigEndianBitConverter.ToUInt32(sector, 0x54);
uint lisaTime = BigEndianBitConverter.ToUInt32(sector, 0x58);
infoMddf.dtvc = DateHandlers.LisaToDateTime(lisaTime);
lisaTime = BigEndianBitConverter.ToUInt32(sector, 0x5C);
infoMddf.dtcc = DateHandlers.LisaToDateTime(lisaTime);
lisaTime = BigEndianBitConverter.ToUInt32(sector, 0x60);
infoMddf.dtvb = DateHandlers.LisaToDateTime(lisaTime);
lisaTime = BigEndianBitConverter.ToUInt32(sector, 0x64);
infoMddf.dtvs = DateHandlers.LisaToDateTime(lisaTime);
infoMddf.unknown3 = BigEndianBitConverter.ToUInt32(sector, 0x68);
infoMddf.mddf_block = BigEndianBitConverter.ToUInt32(sector, 0x6C);
infoMddf.volsize_minus_one = BigEndianBitConverter.ToUInt32(sector, 0x70);
infoMddf.dtvc = DateHandlers.LisaToDateTime(lisaTime);
lisaTime = BigEndianBitConverter.ToUInt32(sector, 0x5C);
infoMddf.dtcc = DateHandlers.LisaToDateTime(lisaTime);
lisaTime = BigEndianBitConverter.ToUInt32(sector, 0x60);
infoMddf.dtvb = DateHandlers.LisaToDateTime(lisaTime);
lisaTime = BigEndianBitConverter.ToUInt32(sector, 0x64);
infoMddf.dtvs = DateHandlers.LisaToDateTime(lisaTime);
infoMddf.unknown3 = BigEndianBitConverter.ToUInt32(sector, 0x68);
infoMddf.mddf_block = BigEndianBitConverter.ToUInt32(sector, 0x6C);
infoMddf.volsize_minus_one = BigEndianBitConverter.ToUInt32(sector, 0x70);
infoMddf.volsize_minus_mddf_minus_one = BigEndianBitConverter.ToUInt32(sector, 0x74);
infoMddf.vol_size = BigEndianBitConverter.ToUInt32(sector, 0x78);
infoMddf.blocksize = BigEndianBitConverter.ToUInt16(sector, 0x7C);
infoMddf.datasize = BigEndianBitConverter.ToUInt16(sector, 0x7E);
infoMddf.unknown4 = BigEndianBitConverter.ToUInt16(sector, 0x80);
infoMddf.unknown5 = BigEndianBitConverter.ToUInt32(sector, 0x82);
infoMddf.unknown6 = BigEndianBitConverter.ToUInt32(sector, 0x86);
infoMddf.clustersize = BigEndianBitConverter.ToUInt16(sector, 0x8A);
infoMddf.fs_size = BigEndianBitConverter.ToUInt32(sector, 0x8C);
infoMddf.unknown7 = BigEndianBitConverter.ToUInt32(sector, 0x90);
infoMddf.srec_ptr = BigEndianBitConverter.ToUInt32(sector, 0x94);
infoMddf.unknown9 = BigEndianBitConverter.ToUInt16(sector, 0x98);
infoMddf.srec_len = BigEndianBitConverter.ToUInt16(sector, 0x9A);
infoMddf.unknown10 = BigEndianBitConverter.ToUInt32(sector, 0x9C);
infoMddf.unknown11 = BigEndianBitConverter.ToUInt32(sector, 0xA0);
infoMddf.unknown12 = BigEndianBitConverter.ToUInt32(sector, 0xA4);
infoMddf.unknown13 = BigEndianBitConverter.ToUInt32(sector, 0xA8);
infoMddf.unknown14 = BigEndianBitConverter.ToUInt32(sector, 0xAC);
infoMddf.filecount = BigEndianBitConverter.ToUInt16(sector, 0xB0);
infoMddf.unknown15 = BigEndianBitConverter.ToUInt32(sector, 0xB2);
infoMddf.unknown16 = BigEndianBitConverter.ToUInt32(sector, 0xB6);
infoMddf.freecount = BigEndianBitConverter.ToUInt32(sector, 0xBA);
infoMddf.unknown17 = BigEndianBitConverter.ToUInt16(sector, 0xBE);
infoMddf.unknown18 = BigEndianBitConverter.ToUInt32(sector, 0xC0);
infoMddf.overmount_stamp = BigEndianBitConverter.ToUInt64(sector, 0xC4);
infoMddf.serialization = BigEndianBitConverter.ToUInt32(sector, 0xCC);
infoMddf.unknown19 = BigEndianBitConverter.ToUInt32(sector, 0xD0);
infoMddf.unknown_timestamp = BigEndianBitConverter.ToUInt32(sector, 0xD4);
infoMddf.unknown20 = BigEndianBitConverter.ToUInt32(sector, 0xD8);
infoMddf.unknown21 = BigEndianBitConverter.ToUInt32(sector, 0xDC);
infoMddf.unknown22 = BigEndianBitConverter.ToUInt32(sector, 0xE0);
infoMddf.unknown23 = BigEndianBitConverter.ToUInt32(sector, 0xE4);
infoMddf.unknown24 = BigEndianBitConverter.ToUInt32(sector, 0xE8);
infoMddf.unknown25 = BigEndianBitConverter.ToUInt32(sector, 0xEC);
infoMddf.unknown26 = BigEndianBitConverter.ToUInt32(sector, 0xF0);
infoMddf.unknown27 = BigEndianBitConverter.ToUInt32(sector, 0xF4);
infoMddf.unknown28 = BigEndianBitConverter.ToUInt32(sector, 0xF8);
infoMddf.unknown29 = BigEndianBitConverter.ToUInt32(sector, 0xFC);
infoMddf.unknown30 = BigEndianBitConverter.ToUInt32(sector, 0x100);
infoMddf.unknown31 = BigEndianBitConverter.ToUInt32(sector, 0x104);
infoMddf.unknown32 = BigEndianBitConverter.ToUInt32(sector, 0x108);
infoMddf.unknown33 = BigEndianBitConverter.ToUInt32(sector, 0x10C);
infoMddf.unknown34 = BigEndianBitConverter.ToUInt32(sector, 0x110);
infoMddf.unknown35 = BigEndianBitConverter.ToUInt32(sector, 0x114);
infoMddf.backup_volid = BigEndianBitConverter.ToUInt64(sector, 0x118);
infoMddf.label_size = BigEndianBitConverter.ToUInt16(sector, 0x120);
infoMddf.fs_overhead = BigEndianBitConverter.ToUInt16(sector, 0x122);
infoMddf.result_scavenge = BigEndianBitConverter.ToUInt16(sector, 0x124);
infoMddf.boot_code = BigEndianBitConverter.ToUInt16(sector, 0x126);
infoMddf.boot_environ = BigEndianBitConverter.ToUInt16(sector, 0x6C);
infoMddf.unknown36 = BigEndianBitConverter.ToUInt32(sector, 0x12A);
infoMddf.unknown37 = BigEndianBitConverter.ToUInt32(sector, 0x12E);
infoMddf.unknown38 = BigEndianBitConverter.ToUInt32(sector, 0x132);
infoMddf.vol_sequence = BigEndianBitConverter.ToUInt16(sector, 0x136);
infoMddf.vol_left_mounted = sector[0x138];
infoMddf.vol_size = BigEndianBitConverter.ToUInt32(sector, 0x78);
infoMddf.blocksize = BigEndianBitConverter.ToUInt16(sector, 0x7C);
infoMddf.datasize = BigEndianBitConverter.ToUInt16(sector, 0x7E);
infoMddf.unknown4 = BigEndianBitConverter.ToUInt16(sector, 0x80);
infoMddf.unknown5 = BigEndianBitConverter.ToUInt32(sector, 0x82);
infoMddf.unknown6 = BigEndianBitConverter.ToUInt32(sector, 0x86);
infoMddf.clustersize = BigEndianBitConverter.ToUInt16(sector, 0x8A);
infoMddf.fs_size = BigEndianBitConverter.ToUInt32(sector, 0x8C);
infoMddf.unknown7 = BigEndianBitConverter.ToUInt32(sector, 0x90);
infoMddf.srec_ptr = BigEndianBitConverter.ToUInt32(sector, 0x94);
infoMddf.unknown9 = BigEndianBitConverter.ToUInt16(sector, 0x98);
infoMddf.srec_len = BigEndianBitConverter.ToUInt16(sector, 0x9A);
infoMddf.unknown10 = BigEndianBitConverter.ToUInt32(sector, 0x9C);
infoMddf.unknown11 = BigEndianBitConverter.ToUInt32(sector, 0xA0);
infoMddf.unknown12 = BigEndianBitConverter.ToUInt32(sector, 0xA4);
infoMddf.unknown13 = BigEndianBitConverter.ToUInt32(sector, 0xA8);
infoMddf.unknown14 = BigEndianBitConverter.ToUInt32(sector, 0xAC);
infoMddf.filecount = BigEndianBitConverter.ToUInt16(sector, 0xB0);
infoMddf.unknown15 = BigEndianBitConverter.ToUInt32(sector, 0xB2);
infoMddf.unknown16 = BigEndianBitConverter.ToUInt32(sector, 0xB6);
infoMddf.freecount = BigEndianBitConverter.ToUInt32(sector, 0xBA);
infoMddf.unknown17 = BigEndianBitConverter.ToUInt16(sector, 0xBE);
infoMddf.unknown18 = BigEndianBitConverter.ToUInt32(sector, 0xC0);
infoMddf.overmount_stamp = BigEndianBitConverter.ToUInt64(sector, 0xC4);
infoMddf.serialization = BigEndianBitConverter.ToUInt32(sector, 0xCC);
infoMddf.unknown19 = BigEndianBitConverter.ToUInt32(sector, 0xD0);
infoMddf.unknown_timestamp = BigEndianBitConverter.ToUInt32(sector, 0xD4);
infoMddf.unknown20 = BigEndianBitConverter.ToUInt32(sector, 0xD8);
infoMddf.unknown21 = BigEndianBitConverter.ToUInt32(sector, 0xDC);
infoMddf.unknown22 = BigEndianBitConverter.ToUInt32(sector, 0xE0);
infoMddf.unknown23 = BigEndianBitConverter.ToUInt32(sector, 0xE4);
infoMddf.unknown24 = BigEndianBitConverter.ToUInt32(sector, 0xE8);
infoMddf.unknown25 = BigEndianBitConverter.ToUInt32(sector, 0xEC);
infoMddf.unknown26 = BigEndianBitConverter.ToUInt32(sector, 0xF0);
infoMddf.unknown27 = BigEndianBitConverter.ToUInt32(sector, 0xF4);
infoMddf.unknown28 = BigEndianBitConverter.ToUInt32(sector, 0xF8);
infoMddf.unknown29 = BigEndianBitConverter.ToUInt32(sector, 0xFC);
infoMddf.unknown30 = BigEndianBitConverter.ToUInt32(sector, 0x100);
infoMddf.unknown31 = BigEndianBitConverter.ToUInt32(sector, 0x104);
infoMddf.unknown32 = BigEndianBitConverter.ToUInt32(sector, 0x108);
infoMddf.unknown33 = BigEndianBitConverter.ToUInt32(sector, 0x10C);
infoMddf.unknown34 = BigEndianBitConverter.ToUInt32(sector, 0x110);
infoMddf.unknown35 = BigEndianBitConverter.ToUInt32(sector, 0x114);
infoMddf.backup_volid = BigEndianBitConverter.ToUInt64(sector, 0x118);
infoMddf.label_size = BigEndianBitConverter.ToUInt16(sector, 0x120);
infoMddf.fs_overhead = BigEndianBitConverter.ToUInt16(sector, 0x122);
infoMddf.result_scavenge = BigEndianBitConverter.ToUInt16(sector, 0x124);
infoMddf.boot_code = BigEndianBitConverter.ToUInt16(sector, 0x126);
infoMddf.boot_environ = BigEndianBitConverter.ToUInt16(sector, 0x6C);
infoMddf.unknown36 = BigEndianBitConverter.ToUInt32(sector, 0x12A);
infoMddf.unknown37 = BigEndianBitConverter.ToUInt32(sector, 0x12E);
infoMddf.unknown38 = BigEndianBitConverter.ToUInt32(sector, 0x132);
infoMddf.vol_sequence = BigEndianBitConverter.ToUInt16(sector, 0x136);
infoMddf.vol_left_mounted = sector[0x138];
DicConsole.DebugWriteLine("LisaFS plugin", "mddf.unknown1 = 0x{0:X2} ({0})", infoMddf.unknown1);
DicConsole.DebugWriteLine("LisaFS plugin", "mddf.unknown2 = 0x{0:X2} ({0})", infoMddf.unknown2);
DicConsole.DebugWriteLine("LisaFS plugin", "mddf.unknown3 = 0x{0:X8} ({0})", infoMddf.unknown3);
DicConsole.DebugWriteLine("LisaFS plugin", "mddf.unknown4 = 0x{0:X4} ({0})", infoMddf.unknown4);
DicConsole.DebugWriteLine("LisaFS plugin", "mddf.unknown5 = 0x{0:X8} ({0})", infoMddf.unknown5);
DicConsole.DebugWriteLine("LisaFS plugin", "mddf.unknown6 = 0x{0:X8} ({0})", infoMddf.unknown6);
DicConsole.DebugWriteLine("LisaFS plugin", "mddf.unknown7 = 0x{0:X8} ({0})", infoMddf.unknown7);
DicConsole.DebugWriteLine("LisaFS plugin", "mddf.unknown9 = 0x{0:X4} ({0})", infoMddf.unknown9);
DicConsole.DebugWriteLine("LisaFS plugin", "mddf.unknown1 = 0x{0:X2} ({0})", infoMddf.unknown1);
DicConsole.DebugWriteLine("LisaFS plugin", "mddf.unknown2 = 0x{0:X2} ({0})", infoMddf.unknown2);
DicConsole.DebugWriteLine("LisaFS plugin", "mddf.unknown3 = 0x{0:X8} ({0})", infoMddf.unknown3);
DicConsole.DebugWriteLine("LisaFS plugin", "mddf.unknown4 = 0x{0:X4} ({0})", infoMddf.unknown4);
DicConsole.DebugWriteLine("LisaFS plugin", "mddf.unknown5 = 0x{0:X8} ({0})", infoMddf.unknown5);
DicConsole.DebugWriteLine("LisaFS plugin", "mddf.unknown6 = 0x{0:X8} ({0})", infoMddf.unknown6);
DicConsole.DebugWriteLine("LisaFS plugin", "mddf.unknown7 = 0x{0:X8} ({0})", infoMddf.unknown7);
DicConsole.DebugWriteLine("LisaFS plugin", "mddf.unknown9 = 0x{0:X4} ({0})", infoMddf.unknown9);
DicConsole.DebugWriteLine("LisaFS plugin", "mddf.unknown10 = 0x{0:X8} ({0})", infoMddf.unknown10);
DicConsole.DebugWriteLine("LisaFS plugin", "mddf.unknown11 = 0x{0:X8} ({0})", infoMddf.unknown11);
DicConsole.DebugWriteLine("LisaFS plugin", "mddf.unknown12 = 0x{0:X8} ({0})", infoMddf.unknown12);
@@ -352,24 +354,26 @@ namespace DiscImageChef.Filesystems.LisaFS
XmlFsType = new FileSystemType();
if(DateTime.Compare(infoMddf.dtvb, DateHandlers.LisaToDateTime(0)) > 0)
{
XmlFsType.BackupDate = infoMddf.dtvb;
XmlFsType.BackupDate = infoMddf.dtvb;
XmlFsType.BackupDateSpecified = true;
}
XmlFsType.Clusters = infoMddf.vol_size;
XmlFsType.Clusters = infoMddf.vol_size;
XmlFsType.ClusterSize = infoMddf.clustersize * infoMddf.datasize;
if(DateTime.Compare(infoMddf.dtvc, DateHandlers.LisaToDateTime(0)) > 0)
{
XmlFsType.CreationDate = infoMddf.dtvc;
XmlFsType.CreationDate = infoMddf.dtvc;
XmlFsType.CreationDateSpecified = true;
}
XmlFsType.Dirty = infoMddf.vol_left_mounted != 0;
XmlFsType.Files = infoMddf.filecount;
XmlFsType.FilesSpecified = true;
XmlFsType.FreeClusters = infoMddf.freecount;
XmlFsType.Dirty = infoMddf.vol_left_mounted != 0;
XmlFsType.Files = infoMddf.filecount;
XmlFsType.FilesSpecified = true;
XmlFsType.FreeClusters = infoMddf.freecount;
XmlFsType.FreeClustersSpecified = true;
XmlFsType.Type = "LisaFS";
XmlFsType.VolumeName = infoMddf.volname;
XmlFsType.VolumeSerial = $"{infoMddf.volid:X16}";
XmlFsType.Type = "LisaFS";
XmlFsType.VolumeName = infoMddf.volname;
XmlFsType.VolumeSerial = $"{infoMddf.volid:X16}";
return;
}

View File

@@ -58,7 +58,7 @@ namespace DiscImageChef.Filesystems.LisaFS
// TODO: Implement Lisa 7/7 namespace (needs decoding {!CATALOG} file)
public IEnumerable<(string name, Type type, string description)> SupportedOptions =>
new(string name, Type type, string description)[] { };
new (string name, Type type, string description)[] { };
static Dictionary<string, string> GetDefaultOptions()
{

View File

@@ -253,7 +253,7 @@ namespace DiscImageChef.Filesystems.LisaFS
/// </summary>
struct Extent
{
public int start;
public int start;
public short length;
}

View File

@@ -92,8 +92,8 @@ namespace DiscImageChef.Filesystems.LisaFS
devTagSize = device.ReadSectorTag(i, SectorTagType.AppleSectorTag).Length;
byte[] sector = device.ReadSector(i);
mddf = new MDDF();
byte[] sector = device.ReadSector(i);
mddf = new MDDF();
byte[] pString = new byte[33];
mddf.fsversion = BigEndianBitConverter.ToUInt16(sector, 0x00);
@@ -104,11 +104,10 @@ namespace DiscImageChef.Filesystems.LisaFS
mddf.unknown1 = sector[0x2D];
Array.Copy(sector, 0x2E, pString, 0, 33);
// Prevent garbage
mddf.password =
pString[0] <= 32 ? StringHandlers.PascalToString(pString, Encoding) : "";
mddf.unknown2 = sector[0x4F];
mddf.machine_id = BigEndianBitConverter.ToUInt32(sector, 0x50);
mddf.master_copy_id = BigEndianBitConverter.ToUInt32(sector, 0x54);
mddf.password = pString[0] <= 32 ? StringHandlers.PascalToString(pString, Encoding) : "";
mddf.unknown2 = sector[0x4F];
mddf.machine_id = BigEndianBitConverter.ToUInt32(sector, 0x50);
mddf.master_copy_id = BigEndianBitConverter.ToUInt32(sector, 0x54);
uint lisaTime = BigEndianBitConverter.ToUInt32(sector, 0x58);
mddf.dtvc = DateHandlers.LisaToDateTime(lisaTime);
lisaTime = BigEndianBitConverter.ToUInt32(sector, 0x5C);
@@ -177,13 +176,13 @@ namespace DiscImageChef.Filesystems.LisaFS
mddf.vol_left_mounted = sector[0x138];
// Check that the MDDF is correct
if(mddf.mddf_block != i - volumePrefix ||
mddf.vol_size > device.Info.Sectors ||
if(mddf.mddf_block != i - volumePrefix ||
mddf.vol_size > device.Info.Sectors ||
mddf.vol_size - 1 !=
mddf.volsize_minus_one ||
mddf.vol_size - i - 1 !=
mddf.vol_size - i - 1 !=
mddf.volsize_minus_mddf_minus_one - volumePrefix ||
mddf.datasize >
mddf.datasize >
mddf.blocksize || mddf.blocksize < device.Info.SectorSize ||
mddf.datasize != device.Info.SectorSize)
{
@@ -215,7 +214,7 @@ namespace DiscImageChef.Filesystems.LisaFS
//catalogCache = new Dictionary<short, List<CatalogEntry>>();
fileSizeCache = new Dictionary<short, int>();
mounted = true;
mounted = true;
if(options == null) options = GetDefaultOptions();
if(options.TryGetValue("debug", out string debugString)) bool.TryParse(debugString, out debug);

View File

@@ -57,20 +57,20 @@ namespace DiscImageChef.Filesystems
{
public class Locus : IFilesystem
{
const int NICINOD = 325;
const int NICFREE = 600;
const int NICINOD = 325;
const int NICFREE = 600;
const int OLDNICINOD = 700;
const int OLDNICFREE = 500;
const uint LOCUS_MAGIC = 0xFFEEDDCD;
const uint LOCUS_CIGAM = 0xCDDDEEFF;
const uint LOCUS_MAGIC = 0xFFEEDDCD;
const uint LOCUS_CIGAM = 0xCDDDEEFF;
const uint LOCUS_MAGIC_OLD = 0xFFEEDDCC;
const uint LOCUS_CIGAM_OLD = 0xCCDDEEFF;
public FileSystemType XmlFsType { get; private set; }
public Encoding Encoding { get; private set; }
public string Name => "Locus Filesystem Plugin";
public Guid Id => new Guid("1A70B30A-437D-479A-88E1-D0C9C1797FF4");
public Encoding Encoding { get; private set; }
public string Name => "Locus Filesystem Plugin";
public Guid Id => new Guid("1A70B30A-437D-479A-88E1-D0C9C1797FF4");
public bool Identify(IMediaImage imagePlugin, Partition partition)
{
@@ -95,7 +95,7 @@ namespace DiscImageChef.Filesystems
DicConsole.DebugWriteLine("Locus plugin", "magic at {1} = 0x{0:X8}", locusSb.s_magic, location);
if(locusSb.s_magic == LOCUS_MAGIC || locusSb.s_magic == LOCUS_CIGAM ||
if(locusSb.s_magic == LOCUS_MAGIC || locusSb.s_magic == LOCUS_CIGAM ||
locusSb.s_magic == LOCUS_MAGIC_OLD || locusSb.s_magic == LOCUS_CIGAM_OLD) return true;
}
@@ -103,14 +103,14 @@ namespace DiscImageChef.Filesystems
}
public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
Encoding encoding)
Encoding encoding)
{
Encoding = encoding ?? Encoding.GetEncoding("iso-8859-15");
Encoding = encoding ?? Encoding.GetEncoding("iso-8859-15");
information = "";
if(imagePlugin.Info.SectorSize < 512) return;
Locus_Superblock locusSb = new Locus_Superblock();
byte[] sector = null;
byte[] sector = null;
for(ulong location = 0; location <= 8; location++)
{
@@ -125,7 +125,7 @@ namespace DiscImageChef.Filesystems
locusSb = (Locus_Superblock)Marshal.PtrToStructure(sbPtr, typeof(Locus_Superblock));
Marshal.FreeHGlobal(sbPtr);
if(locusSb.s_magic == LOCUS_MAGIC || locusSb.s_magic == LOCUS_CIGAM ||
if(locusSb.s_magic == LOCUS_MAGIC || locusSb.s_magic == LOCUS_CIGAM ||
locusSb.s_magic == LOCUS_MAGIC_OLD || locusSb.s_magic == LOCUS_CIGAM_OLD) break;
}
@@ -136,7 +136,7 @@ namespace DiscImageChef.Filesystems
// Numerical arrays are not important for information so no need to swap them
if(locusSb.s_magic == LOCUS_CIGAM || locusSb.s_magic == LOCUS_CIGAM_OLD)
{
locusSb = BigEndianMarshal.ByteArrayToStructureBigEndian<Locus_Superblock>(sector);
locusSb = BigEndianMarshal.ByteArrayToStructureBigEndian<Locus_Superblock>(sector);
locusSb.s_flags = (LocusFlags)Swapping.Swap((ushort)locusSb.s_flags);
}
@@ -150,26 +150,26 @@ namespace DiscImageChef.Filesystems
string s_fpack = StringHandlers.CToString(locusSb.s_fpack, Encoding);
DicConsole.DebugWriteLine("Locus plugin", "LocusSb.s_magic = 0x{0:X8}", locusSb.s_magic);
DicConsole.DebugWriteLine("Locus plugin", "LocusSb.s_gfs = {0}", locusSb.s_gfs);
DicConsole.DebugWriteLine("Locus plugin", "LocusSb.s_fsize = {0}", locusSb.s_fsize);
DicConsole.DebugWriteLine("Locus plugin", "LocusSb.s_lwm = {0}", locusSb.s_lwm);
DicConsole.DebugWriteLine("Locus plugin", "LocusSb.s_hwm = {0}", locusSb.s_hwm);
DicConsole.DebugWriteLine("Locus plugin", "LocusSb.s_llst = {0}", locusSb.s_llst);
DicConsole.DebugWriteLine("Locus plugin", "LocusSb.s_fstore = {0}", locusSb.s_fstore);
DicConsole.DebugWriteLine("Locus plugin", "LocusSb.s_time = {0}", locusSb.s_time);
DicConsole.DebugWriteLine("Locus plugin", "LocusSb.s_tfree = {0}", locusSb.s_tfree);
DicConsole.DebugWriteLine("Locus plugin", "LocusSb.s_isize = {0}", locusSb.s_isize);
DicConsole.DebugWriteLine("Locus plugin", "LocusSb.s_nfree = {0}", locusSb.s_nfree);
DicConsole.DebugWriteLine("Locus plugin", "LocusSb.s_flags = {0}", locusSb.s_flags);
DicConsole.DebugWriteLine("Locus plugin", "LocusSb.s_tinode = {0}", locusSb.s_tinode);
DicConsole.DebugWriteLine("Locus plugin", "LocusSb.s_lasti = {0}", locusSb.s_lasti);
DicConsole.DebugWriteLine("Locus plugin", "LocusSb.s_nbehind = {0}", locusSb.s_nbehind);
DicConsole.DebugWriteLine("Locus plugin", "LocusSb.s_gfspack = {0}", locusSb.s_gfspack);
DicConsole.DebugWriteLine("Locus plugin", "LocusSb.s_ninode = {0}", locusSb.s_ninode);
DicConsole.DebugWriteLine("Locus plugin", "LocusSb.s_flock = {0}", locusSb.s_flock);
DicConsole.DebugWriteLine("Locus plugin", "LocusSb.s_ilock = {0}", locusSb.s_ilock);
DicConsole.DebugWriteLine("Locus plugin", "LocusSb.s_fmod = {0}", locusSb.s_fmod);
DicConsole.DebugWriteLine("Locus plugin", "LocusSb.s_version = {0}", locusSb.s_version);
DicConsole.DebugWriteLine("Locus plugin", "LocusSb.s_gfs = {0}", locusSb.s_gfs);
DicConsole.DebugWriteLine("Locus plugin", "LocusSb.s_fsize = {0}", locusSb.s_fsize);
DicConsole.DebugWriteLine("Locus plugin", "LocusSb.s_lwm = {0}", locusSb.s_lwm);
DicConsole.DebugWriteLine("Locus plugin", "LocusSb.s_hwm = {0}", locusSb.s_hwm);
DicConsole.DebugWriteLine("Locus plugin", "LocusSb.s_llst = {0}", locusSb.s_llst);
DicConsole.DebugWriteLine("Locus plugin", "LocusSb.s_fstore = {0}", locusSb.s_fstore);
DicConsole.DebugWriteLine("Locus plugin", "LocusSb.s_time = {0}", locusSb.s_time);
DicConsole.DebugWriteLine("Locus plugin", "LocusSb.s_tfree = {0}", locusSb.s_tfree);
DicConsole.DebugWriteLine("Locus plugin", "LocusSb.s_isize = {0}", locusSb.s_isize);
DicConsole.DebugWriteLine("Locus plugin", "LocusSb.s_nfree = {0}", locusSb.s_nfree);
DicConsole.DebugWriteLine("Locus plugin", "LocusSb.s_flags = {0}", locusSb.s_flags);
DicConsole.DebugWriteLine("Locus plugin", "LocusSb.s_tinode = {0}", locusSb.s_tinode);
DicConsole.DebugWriteLine("Locus plugin", "LocusSb.s_lasti = {0}", locusSb.s_lasti);
DicConsole.DebugWriteLine("Locus plugin", "LocusSb.s_nbehind = {0}", locusSb.s_nbehind);
DicConsole.DebugWriteLine("Locus plugin", "LocusSb.s_gfspack = {0}", locusSb.s_gfspack);
DicConsole.DebugWriteLine("Locus plugin", "LocusSb.s_ninode = {0}", locusSb.s_ninode);
DicConsole.DebugWriteLine("Locus plugin", "LocusSb.s_flock = {0}", locusSb.s_flock);
DicConsole.DebugWriteLine("Locus plugin", "LocusSb.s_ilock = {0}", locusSb.s_ilock);
DicConsole.DebugWriteLine("Locus plugin", "LocusSb.s_fmod = {0}", locusSb.s_fmod);
DicConsole.DebugWriteLine("Locus plugin", "LocusSb.s_version = {0}", locusSb.s_version);
sb.AppendFormat("Superblock last modified on {0}", DateHandlers.UnixToDateTime(locusSb.s_time))
.AppendLine();
@@ -202,15 +202,16 @@ namespace DiscImageChef.Filesystems
XmlFsType = new FileSystemType
{
Type = "Locus filesystem",
Type = "Locus filesystem",
ClusterSize = blockSize,
Clusters = locusSb.s_fsize,
Clusters = locusSb.s_fsize,
// Sometimes it uses one, or the other. Use the bigger
VolumeName = string.IsNullOrEmpty(s_fsmnt) ? s_fpack : s_fsmnt,
ModificationDate = DateHandlers.UnixToDateTime(locusSb.s_time),
VolumeName = string.IsNullOrEmpty(s_fsmnt) ? s_fpack : s_fsmnt,
ModificationDate = DateHandlers.UnixToDateTime(locusSb.s_time),
ModificationDateSpecified = true,
Dirty = !locusSb.s_flags.HasFlag(LocusFlags.SB_CLEAN) || locusSb.s_flags.HasFlag(LocusFlags.SB_DIRTY),
FreeClusters = locusSb.s_tfree,
Dirty = !locusSb.s_flags.HasFlag(LocusFlags.SB_CLEAN) ||
locusSb.s_flags.HasFlag(LocusFlags.SB_DIRTY),
FreeClusters = locusSb.s_tfree,
FreeClustersSpecified = true
};
}
@@ -222,7 +223,7 @@ namespace DiscImageChef.Filesystems
{
public uint s_magic; /* identifies this as a locus filesystem */
/* defined as a constant below */
public gfs_t s_gfs; /* global filesystem number */
public gfs_t s_gfs; /* global filesystem number */
public daddr_t s_fsize; /* size in blocks of entire volume */
/* several ints for replicated filsystems */
public commitcnt_t s_lwm; /* all prior commits propagated */
@@ -237,34 +238,37 @@ namespace DiscImageChef.Filesystems
primary or backbone copy, this bit mask
determines which files are stored */
public time_t s_time; /* last super block update */
public time_t s_time; /* last super block update */
public daddr_t s_tfree; /* total free blocks*/
public ino_t s_isize; /* size in blocks of i-list */
public short s_nfree; /* number of addresses in s_free */
public LocusFlags s_flags; /* filsys flags, defined below */
public ino_t s_tinode; /* total free inodes */
public ino_t s_lasti; /* start place for circular search */
public ino_t s_nbehind; /* est # free inodes before s_lasti */
public pckno_t s_gfspack; /* global filesystem pack number */
public short s_ninode; /* number of i-nodes in s_inode */
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] public short[] s_dinfo; /* interleave stuff */
public ino_t s_isize; /* size in blocks of i-list */
public short s_nfree; /* number of addresses in s_free */
public LocusFlags s_flags; /* filsys flags, defined below */
public ino_t s_tinode; /* total free inodes */
public ino_t s_lasti; /* start place for circular search */
public ino_t s_nbehind; /* est # free inodes before s_lasti */
public pckno_t s_gfspack; /* global filesystem pack number */
public short s_ninode; /* number of i-nodes in s_inode */
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public short[] s_dinfo; /* interleave stuff */
//#define s_m s_dinfo[0]
//#define s_skip s_dinfo[0] /* AIX defines */
//#define s_n s_dinfo[1]
//#define s_cyl s_dinfo[1] /* AIX defines */
public byte s_flock; /* lock during free list manipulation */
public byte s_ilock; /* lock during i-list manipulation */
public byte s_fmod; /* super block modified flag */
public byte s_flock; /* lock during free list manipulation */
public byte s_ilock; /* lock during i-list manipulation */
public byte s_fmod; /* super block modified flag */
public LocusVersion s_version; /* version of the data format in fs. */
/* defined below. */
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] public byte[] s_fsmnt; /* name of this file system */
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public byte[] s_fsmnt; /* name of this file system */
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public byte[] s_fpack; /* name of this physical volume */
[MarshalAs(UnmanagedType.ByValArray, SizeConst = NICINOD)] public ino_t[] s_inode; /* free i-node list */
[MarshalAs(UnmanagedType.ByValArray, SizeConst = NICINOD)]
public ino_t[] s_inode; /* free i-node list */
[MarshalAs(UnmanagedType.ByValArray, SizeConst = NICFREE)]
public daddr_t[] su_free; /* free block list for non-replicated filsys */
public byte s_byteorder; /* byte order of integers */
public byte s_byteorder; /* byte order of integers */
}
[SuppressMessage("ReSharper", "InconsistentNaming")]
@@ -274,7 +278,7 @@ namespace DiscImageChef.Filesystems
{
public uint s_magic; /* identifies this as a locus filesystem */
/* defined as a constant below */
public gfs_t s_gfs; /* global filesystem number */
public gfs_t s_gfs; /* global filesystem number */
public daddr_t s_fsize; /* size in blocks of entire volume */
/* several ints for replicated filsystems */
public commitcnt_t s_lwm; /* all prior commits propagated */
@@ -289,34 +293,37 @@ namespace DiscImageChef.Filesystems
primary or backbone copy, this bit mask
determines which files are stored */
public time_t s_time; /* last super block update */
public time_t s_time; /* last super block update */
public daddr_t s_tfree; /* total free blocks*/
public ino_t s_isize; /* size in blocks of i-list */
public short s_nfree; /* number of addresses in s_free */
public LocusFlags s_flags; /* filsys flags, defined below */
public ino_t s_tinode; /* total free inodes */
public ino_t s_lasti; /* start place for circular search */
public ino_t s_nbehind; /* est # free inodes before s_lasti */
public pckno_t s_gfspack; /* global filesystem pack number */
public short s_ninode; /* number of i-nodes in s_inode */
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] public short[] s_dinfo; /* interleave stuff */
public ino_t s_isize; /* size in blocks of i-list */
public short s_nfree; /* number of addresses in s_free */
public LocusFlags s_flags; /* filsys flags, defined below */
public ino_t s_tinode; /* total free inodes */
public ino_t s_lasti; /* start place for circular search */
public ino_t s_nbehind; /* est # free inodes before s_lasti */
public pckno_t s_gfspack; /* global filesystem pack number */
public short s_ninode; /* number of i-nodes in s_inode */
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public short[] s_dinfo; /* interleave stuff */
//#define s_m s_dinfo[0]
//#define s_skip s_dinfo[0] /* AIX defines */
//#define s_n s_dinfo[1]
//#define s_cyl s_dinfo[1] /* AIX defines */
public byte s_flock; /* lock during free list manipulation */
public byte s_ilock; /* lock during i-list manipulation */
public byte s_fmod; /* super block modified flag */
public byte s_flock; /* lock during free list manipulation */
public byte s_ilock; /* lock during i-list manipulation */
public byte s_fmod; /* super block modified flag */
public LocusVersion s_version; /* version of the data format in fs. */
/* defined below. */
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] public byte[] s_fsmnt; /* name of this file system */
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public byte[] s_fsmnt; /* name of this file system */
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public byte[] s_fpack; /* name of this physical volume */
[MarshalAs(UnmanagedType.ByValArray, SizeConst = OLDNICINOD)] public ino_t[] s_inode; /* free i-node list */
[MarshalAs(UnmanagedType.ByValArray, SizeConst = OLDNICINOD)]
public ino_t[] s_inode; /* free i-node list */
[MarshalAs(UnmanagedType.ByValArray, SizeConst = OLDNICFREE)]
public daddr_t[] su_free; /* free block list for non-replicated filsys */
public byte s_byteorder; /* byte order of integers */
public byte s_byteorder; /* byte order of integers */
}
[SuppressMessage("ReSharper", "InconsistentNaming")]
@@ -324,18 +331,18 @@ namespace DiscImageChef.Filesystems
[Flags]
enum LocusFlags : ushort
{
SB_RDONLY = 0x1, /* no writes on filesystem */
SB_CLEAN = 0x2, /* fs unmounted cleanly (or checks run) */
SB_DIRTY = 0x4, /* fs mounted without CLEAN bit set */
SB_RMV = 0x8, /* fs is a removable file system */
SB_PRIMPACK = 0x10, /* This is the primary pack of the filesystem */
SB_REPLTYPE = 0x20, /* This is a replicated type filesystem. */
SB_USER = 0x40, /* This is a "user" replicated filesystem. */
SB_BACKBONE = 0x80, /* backbone pack ; complete copy of primary pack but not modifiable */
SB_NFS = 0x100, /* This is a NFS type filesystem */
SB_BYHAND = 0x200, /* Inhibits automatic fscks on a mangled file system */
SB_NOSUID = 0x400, /* Set-uid/Set-gid is disabled */
SB_SYNCW = 0x800 /* Synchronous Write */
SB_RDONLY = 0x1, /* no writes on filesystem */
SB_CLEAN = 0x2, /* fs unmounted cleanly (or checks run) */
SB_DIRTY = 0x4, /* fs mounted without CLEAN bit set */
SB_RMV = 0x8, /* fs is a removable file system */
SB_PRIMPACK = 0x10, /* This is the primary pack of the filesystem */
SB_REPLTYPE = 0x20, /* This is a replicated type filesystem. */
SB_USER = 0x40, /* This is a "user" replicated filesystem. */
SB_BACKBONE = 0x80, /* backbone pack ; complete copy of primary pack but not modifiable */
SB_NFS = 0x100, /* This is a NFS type filesystem */
SB_BYHAND = 0x200, /* Inhibits automatic fscks on a mangled file system */
SB_NOSUID = 0x400, /* Set-uid/Set-gid is disabled */
SB_SYNCW = 0x800 /* Synchronous Write */
}
[SuppressMessage("ReSharper", "InconsistentNaming")]
@@ -343,9 +350,9 @@ namespace DiscImageChef.Filesystems
[Flags]
enum LocusVersion : byte
{
SB_SB4096 = 1, /* smallblock filesys with 4096 byte blocks */
SB_B1024 = 2, /* 1024 byte block filesystem */
NUMSCANDEV = 5 /* Used by scangfs(), refed in space.h */
SB_SB4096 = 1, /* smallblock filesys with 4096 byte blocks */
SB_B1024 = 2, /* 1024 byte block filesystem */
NUMSCANDEV = 5 /* Used by scangfs(), refed in space.h */
}
}
}

View File

@@ -43,13 +43,13 @@ namespace DiscImageChef.Filesystems
// Thanks to tarlabnor for translating it
public class MicroDOS : IFilesystem
{
const ushort MAGIC = 0xA72E;
const ushort MAGIC = 0xA72E;
const ushort MAGIC2 = 0x530C;
public FileSystemType XmlFsType { get; private set; }
public Encoding Encoding { get; private set; }
public string Name => "MicroDOS file system";
public Guid Id => new Guid("9F9A364A-1A27-48A3-B730-7A7122000324");
public Encoding Encoding { get; private set; }
public string Name => "MicroDOS file system";
public Guid Id => new Guid("9F9A364A-1A27-48A3-B730-7A7122000324");
public bool Identify(IMediaImage imagePlugin, Partition partition)
{
@@ -68,9 +68,9 @@ namespace DiscImageChef.Filesystems
}
public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
Encoding encoding)
Encoding encoding)
{
Encoding = encoding ?? Encoding.GetEncoding("koi8-r");
Encoding = encoding ?? Encoding.GetEncoding("koi8-r");
information = "";
StringBuilder sb = new StringBuilder();
@@ -91,12 +91,12 @@ namespace DiscImageChef.Filesystems
XmlFsType = new FileSystemType
{
Type = "MicroDOS",
ClusterSize = 512,
Clusters = block0.blocks,
Files = block0.files,
FilesSpecified = true,
FreeClusters = block0.blocks - block0.usedBlocks,
Type = "MicroDOS",
ClusterSize = 512,
Clusters = block0.blocks,
Files = block0.files,
FilesSpecified = true,
FreeClusters = block0.blocks - block0.usedBlocks,
FreeClustersSpecified = true
};
@@ -108,19 +108,22 @@ namespace DiscImageChef.Filesystems
struct MicroDosBlock0
{
/// <summary>BK starts booting here</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 24)] public byte[] bootCode;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 24)]
public byte[] bootCode;
/// <summary>Number of files in directory</summary>
public ushort files;
/// <summary>Total number of blocks in files of the directory</summary>
public ushort usedBlocks;
/// <summary>Unknown</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 228)] public byte[] unknown;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 228)]
public byte[] unknown;
/// <summary>Ownership label (label that shows it belongs to Micro DOS format)</summary>
public ushort label;
/// <summary>MK-DOS directory format label</summary>
public ushort mklabel;
/// <summary>Unknown</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 50)] public byte[] unknown2;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 50)]
public byte[] unknown2;
/// <summary>
/// Disk size in blocks (absolute value for the system unlike NORD, NORTON etc.) that
/// doesn't use two fixed values 40 or 80 tracks, but i.e. if you drive works with 76 tracks
@@ -130,7 +133,8 @@ namespace DiscImageChef.Filesystems
/// <summary> Number of the first file's block. Value is changable</summary>
public ushort firstUsedBlock;
/// <summary>Unknown</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)] public byte[] unknown3;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
public byte[] unknown3;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
@@ -141,7 +145,8 @@ namespace DiscImageChef.Filesystems
/// <summary>Directory number (0 - root)</summary>
public byte directory;
/// <summary>File name 14. symbols in ASCII KOI8</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)] public byte[] filename;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)]
public byte[] filename;
/// <summary>Block number</summary>
public ushort blockNo;
/// <summary>Length in blocks</summary>
@@ -154,11 +159,11 @@ namespace DiscImageChef.Filesystems
enum FileStatus : byte
{
CommonFile = 0,
Protected = 1,
CommonFile = 0,
Protected = 1,
LogicalDisk = 2,
BadFile = 0x80,
Deleted = 0xFF
BadFile = 0x80,
Deleted = 0xFF
}
}
}

View File

@@ -65,9 +65,9 @@ namespace DiscImageChef.Filesystems
const ushort MINIX3_CIGAM = 0x5A4D;
public FileSystemType XmlFsType { get; private set; }
public Encoding Encoding { get; private set; }
public string Name => "Minix Filesystem";
public Guid Id => new Guid("FE248C3B-B727-4AE5-A39F-79EA9A07D4B3");
public Encoding Encoding { get; private set; }
public string Name => "Minix Filesystem";
public Guid Id => new Guid("FE248C3B-B727-4AE5-A39F-79EA9A07D4B3");
public bool Identify(IMediaImage imagePlugin, Partition partition)
{
@@ -105,9 +105,9 @@ namespace DiscImageChef.Filesystems
}
public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
Encoding encoding)
Encoding encoding)
{
Encoding = encoding ?? Encoding.GetEncoding("iso-8859-15");
Encoding = encoding ?? Encoding.GetEncoding("iso-8859-15");
information = "";
StringBuilder sb = new StringBuilder();
@@ -121,8 +121,8 @@ namespace DiscImageChef.Filesystems
offset = 0x400;
}
bool minix3 = false;
int filenamesize;
bool minix3 = false;
int filenamesize;
string minixVersion;
byte[] minixSbSector = imagePlugin.ReadSector(sector + partition.Start);
@@ -141,7 +141,7 @@ namespace DiscImageChef.Filesystems
bool littleEndian;
if(magic == MINIX3_MAGIC || magic == MINIX3_CIGAM || magic == MINIX2_MAGIC || magic == MINIX2_CIGAM ||
magic == MINIX_MAGIC || magic == MINIX_CIGAM)
magic == MINIX_MAGIC || magic == MINIX_CIGAM)
{
filenamesize = 60;
littleEndian = magic != MINIX3_CIGAM || magic == MINIX2_CIGAM || magic == MINIX_CIGAM;
@@ -150,16 +150,16 @@ namespace DiscImageChef.Filesystems
{
case MINIX3_MAGIC:
case MINIX3_CIGAM:
minixVersion = "Minix v3 filesystem";
minixVersion = "Minix v3 filesystem";
XmlFsType.Type = "Minix v3";
break;
case MINIX2_MAGIC:
case MINIX2_CIGAM:
minixVersion = "Minix 3 v2 filesystem";
minixVersion = "Minix 3 v2 filesystem";
XmlFsType.Type = "Minix 3 v2";
break;
default:
minixVersion = "Minix 3 v1 filesystem";
minixVersion = "Minix 3 v1 filesystem";
XmlFsType.Type = "Minix 3 v1";
break;
}
@@ -173,51 +173,51 @@ namespace DiscImageChef.Filesystems
switch(magic)
{
case MINIX_MAGIC:
filenamesize = 14;
minixVersion = "Minix v1 filesystem";
littleEndian = true;
filenamesize = 14;
minixVersion = "Minix v1 filesystem";
littleEndian = true;
XmlFsType.Type = "Minix v1";
break;
case MINIX_MAGIC2:
filenamesize = 30;
minixVersion = "Minix v1 filesystem";
littleEndian = true;
filenamesize = 30;
minixVersion = "Minix v1 filesystem";
littleEndian = true;
XmlFsType.Type = "Minix v1";
break;
case MINIX2_MAGIC:
filenamesize = 14;
minixVersion = "Minix v2 filesystem";
littleEndian = true;
filenamesize = 14;
minixVersion = "Minix v2 filesystem";
littleEndian = true;
XmlFsType.Type = "Minix v2";
break;
case MINIX2_MAGIC2:
filenamesize = 30;
minixVersion = "Minix v2 filesystem";
littleEndian = true;
filenamesize = 30;
minixVersion = "Minix v2 filesystem";
littleEndian = true;
XmlFsType.Type = "Minix v2";
break;
case MINIX_CIGAM:
filenamesize = 14;
minixVersion = "Minix v1 filesystem";
littleEndian = false;
filenamesize = 14;
minixVersion = "Minix v1 filesystem";
littleEndian = false;
XmlFsType.Type = "Minix v1";
break;
case MINIX_CIGAM2:
filenamesize = 30;
minixVersion = "Minix v1 filesystem";
littleEndian = false;
filenamesize = 30;
minixVersion = "Minix v1 filesystem";
littleEndian = false;
XmlFsType.Type = "Minix v1";
break;
case MINIX2_CIGAM:
filenamesize = 14;
minixVersion = "Minix v2 filesystem";
littleEndian = false;
filenamesize = 14;
minixVersion = "Minix v2 filesystem";
littleEndian = false;
XmlFsType.Type = "Minix v2";
break;
case MINIX2_CIGAM2:
filenamesize = 30;
minixVersion = "Minix v2 filesystem";
littleEndian = false;
filenamesize = 30;
minixVersion = "Minix v2 filesystem";
littleEndian = false;
XmlFsType.Type = "Minix v2";
break;
default: return;
@@ -259,7 +259,7 @@ namespace DiscImageChef.Filesystems
sb.AppendFormat("On-disk filesystem version: {0}", mnxSb.s_disk_version).AppendLine();
XmlFsType.ClusterSize = mnxSb.s_blocksize;
XmlFsType.Clusters = mnxSb.s_zones > 0 ? mnxSb.s_zones : mnxSb.s_nzones;
XmlFsType.Clusters = mnxSb.s_zones > 0 ? mnxSb.s_zones : mnxSb.s_nzones;
}
else
{
@@ -292,8 +292,9 @@ namespace DiscImageChef.Filesystems
sb.AppendFormat("{0} bytes maximum per file", mnxSb.s_max_size).AppendLine();
sb.AppendFormat("Filesystem state: {0:X4}", mnxSb.s_state).AppendLine();
XmlFsType.ClusterSize = 1024;
XmlFsType.Clusters = mnxSb.s_zones > 0 ? mnxSb.s_zones : mnxSb.s_nzones;
XmlFsType.Clusters = mnxSb.s_zones > 0 ? mnxSb.s_zones : mnxSb.s_nzones;
}
information = sb.ToString();
}

View File

@@ -41,19 +41,19 @@ namespace DiscImageChef.Filesystems
{
public class NILFS2 : IFilesystem
{
const ushort NILFS2_MAGIC = 0x3434;
const uint NILFS2_SUPER_OFFSET = 1024;
const ushort NILFS2_MAGIC = 0x3434;
const uint NILFS2_SUPER_OFFSET = 1024;
public FileSystemType XmlFsType { get; private set; }
public Encoding Encoding { get; private set; }
public string Name => "NILFS2 Plugin";
public Guid Id => new Guid("35224226-C5CC-48B5-8FFD-3781E91E86B6");
public Encoding Encoding { get; private set; }
public string Name => "NILFS2 Plugin";
public Guid Id => new Guid("35224226-C5CC-48B5-8FFD-3781E91E86B6");
public bool Identify(IMediaImage imagePlugin, Partition partition)
{
if(imagePlugin.Info.SectorSize < 512) return false;
uint sbAddr = NILFS2_SUPER_OFFSET / imagePlugin.Info.SectorSize;
uint sbAddr = NILFS2_SUPER_OFFSET / imagePlugin.Info.SectorSize;
if(sbAddr == 0) sbAddr = 1;
NILFS2_Superblock nilfsSb = new NILFS2_Superblock();
@@ -75,13 +75,13 @@ namespace DiscImageChef.Filesystems
}
public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
Encoding encoding)
Encoding encoding)
{
Encoding = encoding ?? Encoding.UTF8;
Encoding = encoding ?? Encoding.UTF8;
information = "";
if(imagePlugin.Info.SectorSize < 512) return;
uint sbAddr = NILFS2_SUPER_OFFSET / imagePlugin.Info.SectorSize;
uint sbAddr = NILFS2_SUPER_OFFSET / imagePlugin.Info.SectorSize;
if(sbAddr == 0) sbAddr = 1;
NILFS2_Superblock nilfsSb = new NILFS2_Superblock();
@@ -122,13 +122,13 @@ namespace DiscImageChef.Filesystems
XmlFsType = new FileSystemType
{
Type = "NILFS2 filesystem",
ClusterSize = 1 << (int)(nilfsSb.log_block_size + 10),
VolumeName = StringHandlers.CToString(nilfsSb.volume_name, Encoding),
VolumeSerial = nilfsSb.uuid.ToString(),
CreationDate = DateHandlers.UnixUnsignedToDateTime(nilfsSb.ctime),
CreationDateSpecified = true,
ModificationDate = DateHandlers.UnixUnsignedToDateTime(nilfsSb.wtime),
Type = "NILFS2 filesystem",
ClusterSize = 1 << (int)(nilfsSb.log_block_size + 10),
VolumeName = StringHandlers.CToString(nilfsSb.volume_name, Encoding),
VolumeSerial = nilfsSb.uuid.ToString(),
CreationDate = DateHandlers.UnixUnsignedToDateTime(nilfsSb.ctime),
CreationDateSpecified = true,
ModificationDate = DateHandlers.UnixUnsignedToDateTime(nilfsSb.wtime),
ModificationDateSpecified = true
};
if(nilfsSb.creator_os == 0) XmlFsType.SystemIdentifier = "Linux";
@@ -137,52 +137,53 @@ namespace DiscImageChef.Filesystems
enum NILFS2_State : ushort
{
Valid = 0x0001,
Error = 0x0002,
Valid = 0x0001,
Error = 0x0002,
Resize = 0x0004
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct NILFS2_Superblock
{
public uint rev_level;
public ushort minor_rev_level;
public ushort magic;
public ushort bytes;
public ushort flags;
public uint crc_seed;
public uint sum;
public uint log_block_size;
public ulong nsegments;
public ulong dev_size;
public ulong first_data_block;
public uint blocks_per_segment;
public uint r_segments_percentage;
public ulong last_cno;
public ulong last_pseg;
public ulong last_seq;
public ulong free_blocks_count;
public ulong ctime;
public ulong mtime;
public ulong wtime;
public ushort mnt_count;
public ushort max_mnt_count;
public uint rev_level;
public ushort minor_rev_level;
public ushort magic;
public ushort bytes;
public ushort flags;
public uint crc_seed;
public uint sum;
public uint log_block_size;
public ulong nsegments;
public ulong dev_size;
public ulong first_data_block;
public uint blocks_per_segment;
public uint r_segments_percentage;
public ulong last_cno;
public ulong last_pseg;
public ulong last_seq;
public ulong free_blocks_count;
public ulong ctime;
public ulong mtime;
public ulong wtime;
public ushort mnt_count;
public ushort max_mnt_count;
public NILFS2_State state;
public ushort errors;
public ulong lastcheck;
public uint checkinterval;
public uint creator_os;
public ushort def_resuid;
public ushort def_resgid;
public uint first_ino;
public ushort inode_size;
public ushort dat_entry_size;
public ushort checkpoint_size;
public ushort segment_usage_size;
public Guid uuid;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 80)] public byte[] volume_name;
public uint c_interval;
public uint c_block_max;
public ushort errors;
public ulong lastcheck;
public uint checkinterval;
public uint creator_os;
public ushort def_resuid;
public ushort def_resgid;
public uint first_ino;
public ushort inode_size;
public ushort dat_entry_size;
public ushort checkpoint_size;
public ushort segment_usage_size;
public Guid uuid;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 80)]
public byte[] volume_name;
public uint c_interval;
public uint c_block_max;
public ulong feature_compat;
public ulong feature_compat_ro;
public ulong feature_incompat;

View File

@@ -86,7 +86,7 @@ namespace DiscImageChef.Filesystems
NtfsBootBlock ntfsBb = (NtfsBootBlock)Marshal.PtrToStructure(bpbPtr, typeof(NtfsBootBlock));
Marshal.FreeHGlobal(bpbPtr);
sb.AppendFormat("{0} bytes per sector", ntfsBb.bps).AppendLine();
sb.AppendFormat("{0} bytes per sector", ntfsBb.bps).AppendLine();
sb.AppendFormat("{0} sectors per cluster ({1} bytes)", ntfsBb.spc, ntfsBb.spc * ntfsBb.bps).AppendLine();
// sb.AppendFormat("{0} reserved sectors", ntfs_bb.rsectors).AppendLine();
// sb.AppendFormat("{0} FATs", ntfs_bb.fats_no).AppendLine();
@@ -94,8 +94,8 @@ namespace DiscImageChef.Filesystems
// sb.AppendFormat("{0} sectors on volume (small)", ntfs_bb.sml_sectors).AppendLine();
sb.AppendFormat("Media descriptor: 0x{0:X2}", ntfsBb.media).AppendLine();
// sb.AppendFormat("{0} sectors per FAT", ntfs_bb.spfat).AppendLine();
sb.AppendFormat("{0} sectors per track", ntfsBb.sptrk).AppendLine();
sb.AppendFormat("{0} heads", ntfsBb.heads).AppendLine();
sb.AppendFormat("{0} sectors per track", ntfsBb.sptrk).AppendLine();
sb.AppendFormat("{0} heads", ntfsBb.heads).AppendLine();
sb.AppendFormat("{0} hidden sectors before filesystem", ntfsBb.hsectors).AppendLine();
// sb.AppendFormat("{0} sectors on volume (big)", ntfs_bb.big_sectors).AppendLine();
sb.AppendFormat("BIOS drive number: 0x{0:X2}", ntfsBb.drive_no).AppendLine();
@@ -103,7 +103,7 @@ namespace DiscImageChef.Filesystems
// sb.AppendFormat("Signature 1: 0x{0:X2}", ntfs_bb.signature1).AppendLine();
sb.AppendFormat("{0} sectors on volume ({1} bytes)", ntfsBb.sectors, ntfsBb.sectors * ntfsBb.bps)
.AppendLine();
sb.AppendFormat("Cluster where $MFT starts: {0}", ntfsBb.mft_lsn).AppendLine();
sb.AppendFormat("Cluster where $MFT starts: {0}", ntfsBb.mft_lsn).AppendLine();
sb.AppendFormat("Cluster where $MFTMirr starts: {0}", ntfsBb.mftmirror_lsn).AppendLine();
if(ntfsBb.mft_rc_clusters > 0)
@@ -123,7 +123,7 @@ namespace DiscImageChef.Filesystems
if(ntfsBb.jump[0] == 0xEB && ntfsBb.jump[1] > 0x4E && ntfsBb.jump[1] < 0x80 && ntfsBb.signature2 == 0xAA55)
{
XmlFsType.Bootable = true;
string bootChk = Sha1Context.Data(ntfsBb.boot_code, out _);
string bootChk = Sha1Context.Data(ntfsBb.boot_code, out _);
sb.AppendLine("Volume is bootable");
sb.AppendFormat("Boot code's SHA1: {0}", bootChk).AppendLine();
}

View File

@@ -42,9 +42,9 @@ namespace DiscImageChef.Filesystems
public class NintendoPlugin : IFilesystem
{
public FileSystemType XmlFsType { get; private set; }
public Encoding Encoding { get; private set; }
public string Name => "Nintendo optical filesystems";
public Guid Id => new Guid("4675fcb4-4418-4288-9e4a-33d6a4ac1126");
public Encoding Encoding { get; private set; }
public string Name => "Nintendo optical filesystems";
public Guid Id => new Guid("4675fcb4-4418-4288-9e4a-33d6a4ac1126");
public bool Identify(IMediaImage imagePlugin, Partition partition)
{
@@ -56,19 +56,19 @@ namespace DiscImageChef.Filesystems
byte[] header = imagePlugin.ReadSectors(0, 0x50000 / imagePlugin.Info.SectorSize);
uint magicGc = BigEndianBitConverter.ToUInt32(header, 0x1C);
uint magicGc = BigEndianBitConverter.ToUInt32(header, 0x1C);
uint magicWii = BigEndianBitConverter.ToUInt32(header, 0x18);
return magicGc == 0xC2339F3D || magicWii == 0x5D1C9EA3;
}
public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
Encoding encoding)
Encoding encoding)
{
Encoding = encoding ?? Encoding.GetEncoding("shift_jis");
StringBuilder sbInformation = new StringBuilder();
information = "";
XmlFsType = new FileSystemType();
XmlFsType = new FileSystemType();
NintendoFields fields = new NintendoFields();
BigEndianBitConverter.IsLittleEndian = BitConverter.IsLittleEndian;
@@ -77,33 +77,33 @@ namespace DiscImageChef.Filesystems
bool wii = false;
uint magicGc = BigEndianBitConverter.ToUInt32(header, 0x1C);
uint magicGc = BigEndianBitConverter.ToUInt32(header, 0x1C);
uint magicWii = BigEndianBitConverter.ToUInt32(header, 0x18);
if(magicWii == 0x5D1C9EA3) wii = true;
if(magicWii == 0x5D1C9EA3) wii = true;
else if(magicGc != 0xC2339F3D) return;
fields.DiscType = Encoding.ASCII.GetString(header, 0, 1);
fields.GameCode = Encoding.ASCII.GetString(header, 1, 2);
fields.RegionCode = Encoding.ASCII.GetString(header, 3, 1);
fields.PublisherCode = Encoding.ASCII.GetString(header, 4, 2);
fields.DiscId = Encoding.ASCII.GetString(header, 0, 6);
fields.DiscNumber = header[6];
fields.DiscVersion = header[7];
fields.Streaming |= header[8] > 0;
fields.StreamBufferSize = header[9];
fields.DiscType = Encoding.ASCII.GetString(header, 0, 1);
fields.GameCode = Encoding.ASCII.GetString(header, 1, 2);
fields.RegionCode = Encoding.ASCII.GetString(header, 3, 1);
fields.PublisherCode = Encoding.ASCII.GetString(header, 4, 2);
fields.DiscId = Encoding.ASCII.GetString(header, 0, 6);
fields.DiscNumber = header[6];
fields.DiscVersion = header[7];
fields.Streaming |= header[8] > 0;
fields.StreamBufferSize = header[9];
byte[] temp = new byte[64];
Array.Copy(header, 0x20, temp, 0, 64);
fields.Title = StringHandlers.CToString(temp, Encoding);
if(!wii)
{
fields.DebugOff = BigEndianBitConverter.ToUInt32(header, 0x0400);
fields.DebugOff = BigEndianBitConverter.ToUInt32(header, 0x0400);
fields.DebugAddr = BigEndianBitConverter.ToUInt32(header, 0x0404);
fields.DolOff = BigEndianBitConverter.ToUInt32(header, 0x0420);
fields.FstOff = BigEndianBitConverter.ToUInt32(header, 0x0424);
fields.FstSize = BigEndianBitConverter.ToUInt32(header, 0x0428);
fields.FstMax = BigEndianBitConverter.ToUInt32(header, 0x042C);
fields.DolOff = BigEndianBitConverter.ToUInt32(header, 0x0420);
fields.FstOff = BigEndianBitConverter.ToUInt32(header, 0x0424);
fields.FstSize = BigEndianBitConverter.ToUInt32(header, 0x0428);
fields.FstMax = BigEndianBitConverter.ToUInt32(header, 0x042C);
}
if(wii)
@@ -113,9 +113,9 @@ namespace DiscImageChef.Filesystems
uint offset3 = BigEndianBitConverter.ToUInt32(header, 0x40014) << 2;
uint offset4 = BigEndianBitConverter.ToUInt32(header, 0x4001C) << 2;
fields.FirstPartitions = new NintendoPartition[BigEndianBitConverter.ToUInt32(header, 0x40000)];
fields.FirstPartitions = new NintendoPartition[BigEndianBitConverter.ToUInt32(header, 0x40000)];
fields.SecondPartitions = new NintendoPartition[BigEndianBitConverter.ToUInt32(header, 0x40008)];
fields.ThirdPartitions = new NintendoPartition[BigEndianBitConverter.ToUInt32(header, 0x40010)];
fields.ThirdPartitions = new NintendoPartition[BigEndianBitConverter.ToUInt32(header, 0x40010)];
fields.FourthPartitions = new NintendoPartition[BigEndianBitConverter.ToUInt32(header, 0x40018)];
for(int i = 0; i < fields.FirstPartitions.Length; i++)
@@ -154,41 +154,41 @@ namespace DiscImageChef.Filesystems
BigEndianBitConverter.ToUInt32(header, (int)(offset4 + i * 8 + 4));
}
fields.Region = header[0x4E000];
fields.JapanAge = header[0x4E010];
fields.UsaAge = header[0x4E011];
fields.GermanAge = header[0x4E013];
fields.PegiAge = header[0x4E014];
fields.FinlandAge = header[0x4E015];
fields.PortugalAge = header[0x4E016];
fields.UkAge = header[0x4E017];
fields.Region = header[0x4E000];
fields.JapanAge = header[0x4E010];
fields.UsaAge = header[0x4E011];
fields.GermanAge = header[0x4E013];
fields.PegiAge = header[0x4E014];
fields.FinlandAge = header[0x4E015];
fields.PortugalAge = header[0x4E016];
fields.UkAge = header[0x4E017];
fields.AustraliaAge = header[0x4E018];
fields.KoreaAge = header[0x4E019];
fields.KoreaAge = header[0x4E019];
}
else
{
fields.FirstPartitions = new NintendoPartition[0];
fields.FirstPartitions = new NintendoPartition[0];
fields.SecondPartitions = new NintendoPartition[0];
fields.ThirdPartitions = new NintendoPartition[0];
fields.ThirdPartitions = new NintendoPartition[0];
fields.FourthPartitions = new NintendoPartition[0];
}
DicConsole.DebugWriteLine("Nintendo plugin", "discType = {0}", fields.DiscType);
DicConsole.DebugWriteLine("Nintendo plugin", "gameCode = {0}", fields.GameCode);
DicConsole.DebugWriteLine("Nintendo plugin", "regionCode = {0}", fields.RegionCode);
DicConsole.DebugWriteLine("Nintendo plugin", "publisherCode = {0}", fields.PublisherCode);
DicConsole.DebugWriteLine("Nintendo plugin", "discID = {0}", fields.DiscId);
DicConsole.DebugWriteLine("Nintendo plugin", "discNumber = {0}", fields.DiscNumber);
DicConsole.DebugWriteLine("Nintendo plugin", "discVersion = {0}", fields.DiscVersion);
DicConsole.DebugWriteLine("Nintendo plugin", "streaming = {0}", fields.Streaming);
DicConsole.DebugWriteLine("Nintendo plugin", "discType = {0}", fields.DiscType);
DicConsole.DebugWriteLine("Nintendo plugin", "gameCode = {0}", fields.GameCode);
DicConsole.DebugWriteLine("Nintendo plugin", "regionCode = {0}", fields.RegionCode);
DicConsole.DebugWriteLine("Nintendo plugin", "publisherCode = {0}", fields.PublisherCode);
DicConsole.DebugWriteLine("Nintendo plugin", "discID = {0}", fields.DiscId);
DicConsole.DebugWriteLine("Nintendo plugin", "discNumber = {0}", fields.DiscNumber);
DicConsole.DebugWriteLine("Nintendo plugin", "discVersion = {0}", fields.DiscVersion);
DicConsole.DebugWriteLine("Nintendo plugin", "streaming = {0}", fields.Streaming);
DicConsole.DebugWriteLine("Nintendo plugin", "streamBufferSize = {0}", fields.StreamBufferSize);
DicConsole.DebugWriteLine("Nintendo plugin", "title = \"{0}\"", fields.Title);
DicConsole.DebugWriteLine("Nintendo plugin", "debugOff = 0x{0:X8}", fields.DebugOff);
DicConsole.DebugWriteLine("Nintendo plugin", "debugAddr = 0x{0:X8}", fields.DebugAddr);
DicConsole.DebugWriteLine("Nintendo plugin", "dolOff = 0x{0:X8}", fields.DolOff);
DicConsole.DebugWriteLine("Nintendo plugin", "fstOff = 0x{0:X8}", fields.FstOff);
DicConsole.DebugWriteLine("Nintendo plugin", "fstSize = {0}", fields.FstSize);
DicConsole.DebugWriteLine("Nintendo plugin", "fstMax = {0}", fields.FstMax);
DicConsole.DebugWriteLine("Nintendo plugin", "title = \"{0}\"", fields.Title);
DicConsole.DebugWriteLine("Nintendo plugin", "debugOff = 0x{0:X8}", fields.DebugOff);
DicConsole.DebugWriteLine("Nintendo plugin", "debugAddr = 0x{0:X8}", fields.DebugAddr);
DicConsole.DebugWriteLine("Nintendo plugin", "dolOff = 0x{0:X8}", fields.DolOff);
DicConsole.DebugWriteLine("Nintendo plugin", "fstOff = 0x{0:X8}", fields.FstOff);
DicConsole.DebugWriteLine("Nintendo plugin", "fstSize = {0}", fields.FstSize);
DicConsole.DebugWriteLine("Nintendo plugin", "fstMax = {0}", fields.FstMax);
for(int i = 0; i < fields.FirstPartitions.Length; i++)
{
DicConsole.DebugWriteLine("Nintendo plugin", "firstPartitions[{1}].offset = {0}",
@@ -196,6 +196,7 @@ namespace DiscImageChef.Filesystems
DicConsole.DebugWriteLine("Nintendo plugin", "firstPartitions[{1}].type = {0}",
fields.FirstPartitions[i].Type, i);
}
for(int i = 0; i < fields.SecondPartitions.Length; i++)
{
DicConsole.DebugWriteLine("Nintendo plugin", "secondPartitions[{1}].offset = {0}",
@@ -203,6 +204,7 @@ namespace DiscImageChef.Filesystems
DicConsole.DebugWriteLine("Nintendo plugin", "secondPartitions[{1}].type = {0}",
fields.SecondPartitions[i].Type, i);
}
for(int i = 0; i < fields.ThirdPartitions.Length; i++)
{
DicConsole.DebugWriteLine("Nintendo plugin", "thirdPartitions[{1}].offset = {0}",
@@ -210,6 +212,7 @@ namespace DiscImageChef.Filesystems
DicConsole.DebugWriteLine("Nintendo plugin", "thirdPartitions[{1}].type = {0}",
fields.ThirdPartitions[i].Type, i);
}
for(int i = 0; i < fields.FourthPartitions.Length; i++)
{
DicConsole.DebugWriteLine("Nintendo plugin", "fourthPartitions[{1}].offset = {0}",
@@ -218,16 +221,16 @@ namespace DiscImageChef.Filesystems
fields.FourthPartitions[i].Type, i);
}
DicConsole.DebugWriteLine("Nintendo plugin", "region = {0}", fields.Region);
DicConsole.DebugWriteLine("Nintendo plugin", "japanAge = {0}", fields.JapanAge);
DicConsole.DebugWriteLine("Nintendo plugin", "usaAge = {0}", fields.UsaAge);
DicConsole.DebugWriteLine("Nintendo plugin", "germanAge = {0}", fields.GermanAge);
DicConsole.DebugWriteLine("Nintendo plugin", "pegiAge = {0}", fields.PegiAge);
DicConsole.DebugWriteLine("Nintendo plugin", "finlandAge = {0}", fields.FinlandAge);
DicConsole.DebugWriteLine("Nintendo plugin", "portugalAge = {0}", fields.PortugalAge);
DicConsole.DebugWriteLine("Nintendo plugin", "ukAge = {0}", fields.UkAge);
DicConsole.DebugWriteLine("Nintendo plugin", "region = {0}", fields.Region);
DicConsole.DebugWriteLine("Nintendo plugin", "japanAge = {0}", fields.JapanAge);
DicConsole.DebugWriteLine("Nintendo plugin", "usaAge = {0}", fields.UsaAge);
DicConsole.DebugWriteLine("Nintendo plugin", "germanAge = {0}", fields.GermanAge);
DicConsole.DebugWriteLine("Nintendo plugin", "pegiAge = {0}", fields.PegiAge);
DicConsole.DebugWriteLine("Nintendo plugin", "finlandAge = {0}", fields.FinlandAge);
DicConsole.DebugWriteLine("Nintendo plugin", "portugalAge = {0}", fields.PortugalAge);
DicConsole.DebugWriteLine("Nintendo plugin", "ukAge = {0}", fields.UkAge);
DicConsole.DebugWriteLine("Nintendo plugin", "australiaAge = {0}", fields.AustraliaAge);
DicConsole.DebugWriteLine("Nintendo plugin", "koreaAge = {0}", fields.KoreaAge);
DicConsole.DebugWriteLine("Nintendo plugin", "koreaAge = {0}", fields.KoreaAge);
sbInformation.AppendLine("Nintendo optical filesystem");
sbInformation.AppendLine(wii ? "Nintendo Wii Optical Disc" : "Nintendo GameCube Optical Disc");
@@ -286,12 +289,12 @@ namespace DiscImageChef.Filesystems
sbInformation.AppendFormat("FST starts at {0} and has {1} bytes", fields.FstOff, fields.FstSize)
.AppendLine();
information = sbInformation.ToString();
XmlFsType.Bootable = true;
XmlFsType.Clusters = (long)(imagePlugin.Info.Sectors * imagePlugin.Info.SectorSize / 2048);
XmlFsType.ClusterSize = 2048;
XmlFsType.Type = wii ? "Nintendo Wii filesystem" : "Nintendo Gamecube filesystem";
XmlFsType.VolumeName = fields.Title;
information = sbInformation.ToString();
XmlFsType.Bootable = true;
XmlFsType.Clusters = (long)(imagePlugin.Info.Sectors * imagePlugin.Info.SectorSize / 2048);
XmlFsType.ClusterSize = 2048;
XmlFsType.Type = wii ? "Nintendo Wii filesystem" : "Nintendo Gamecube filesystem";
XmlFsType.VolumeName = fields.Title;
XmlFsType.VolumeSerial = fields.DiscId;
}
@@ -394,36 +397,36 @@ namespace DiscImageChef.Filesystems
struct NintendoFields
{
public string DiscType;
public string GameCode;
public string RegionCode;
public string PublisherCode;
public string DiscId;
public byte DiscNumber;
public byte DiscVersion;
public bool Streaming;
public byte StreamBufferSize;
public string Title;
public uint DebugOff;
public uint DebugAddr;
public uint DolOff;
public uint FstOff;
public uint FstSize;
public uint FstMax;
public string DiscType;
public string GameCode;
public string RegionCode;
public string PublisherCode;
public string DiscId;
public byte DiscNumber;
public byte DiscVersion;
public bool Streaming;
public byte StreamBufferSize;
public string Title;
public uint DebugOff;
public uint DebugAddr;
public uint DolOff;
public uint FstOff;
public uint FstSize;
public uint FstMax;
public NintendoPartition[] FirstPartitions;
public NintendoPartition[] SecondPartitions;
public NintendoPartition[] ThirdPartitions;
public NintendoPartition[] FourthPartitions;
public byte Region;
public byte JapanAge;
public byte UsaAge;
public byte GermanAge;
public byte PegiAge;
public byte FinlandAge;
public byte PortugalAge;
public byte UkAge;
public byte AustraliaAge;
public byte KoreaAge;
public byte Region;
public byte JapanAge;
public byte UsaAge;
public byte GermanAge;
public byte PegiAge;
public byte FinlandAge;
public byte PortugalAge;
public byte UkAge;
public byte AustraliaAge;
public byte KoreaAge;
}
struct NintendoPartition

View File

@@ -52,9 +52,9 @@ namespace DiscImageChef.Filesystems
public class ODS : IFilesystem
{
public FileSystemType XmlFsType { get; private set; }
public Encoding Encoding { get; private set; }
public string Name => "Files-11 On-Disk Structure";
public Guid Id => new Guid("de20633c-8021-4384-aeb0-83b0df14491f");
public Encoding Encoding { get; private set; }
public string Name => "Files-11 On-Disk Structure";
public Guid Id => new Guid("de20633c-8021-4384-aeb0-83b0df14491f");
public bool Identify(IMediaImage imagePlugin, Partition partition)
{
@@ -62,7 +62,7 @@ namespace DiscImageChef.Filesystems
if(imagePlugin.Info.SectorSize < 512) return false;
byte[] magicB = new byte[12];
byte[] magicB = new byte[12];
byte[] hbSector = imagePlugin.ReadSector(1 + partition.Start);
Array.Copy(hbSector, 0x1F0, magicB, 0, 12);
@@ -88,9 +88,9 @@ namespace DiscImageChef.Filesystems
}
public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
Encoding encoding)
Encoding encoding)
{
Encoding = encoding ?? Encoding.GetEncoding("iso-8859-1");
Encoding = encoding ?? Encoding.GetEncoding("iso-8859-1");
information = "";
StringBuilder sb = new StringBuilder();
@@ -103,8 +103,8 @@ namespace DiscImageChef.Filesystems
handle.Free();
// Optical disc
if(imagePlugin.Info.XmlMediaType == XmlMediaType.OpticalDisc &&
StringHandlers.CToString(homeblock.format) != "DECFILE11A " &&
if(imagePlugin.Info.XmlMediaType == XmlMediaType.OpticalDisc &&
StringHandlers.CToString(homeblock.format) != "DECFILE11A " &&
StringHandlers.CToString(homeblock.format) != "DECFILE11B ")
{
if(hbSector.Length < 0x400) return;
@@ -113,7 +113,7 @@ namespace DiscImageChef.Filesystems
hbSector = new byte[0x200];
Array.Copy(tmp, 0x200, hbSector, 0, 0x200);
handle = GCHandle.Alloc(hbSector, GCHandleType.Pinned);
handle = GCHandle.Alloc(hbSector, GCHandleType.Pinned);
homeblock = (OdsHomeBlock)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(OdsHomeBlock));
handle.Free();
@@ -121,7 +121,7 @@ namespace DiscImageChef.Filesystems
StringHandlers.CToString(homeblock.format) != "DECFILE11B ") return;
}
if((homeblock.struclev & 0xFF00) != 0x0200 || (homeblock.struclev & 0xFF) != 1 ||
if((homeblock.struclev & 0xFF00) != 0x0200 || (homeblock.struclev & 0xFF) != 1 ||
StringHandlers.CToString(homeblock.format) != "DECFILE11B ")
sb.AppendLine("The following information may be incorrect for this volume.");
if(homeblock.resfiles < 5 || homeblock.devtype != 0) sb.AppendLine("This volume may be corrupted.");
@@ -148,7 +148,7 @@ namespace DiscImageChef.Filesystems
.AppendLine();
sb.AppendFormat("{0} maximum files on the volume", homeblock.maxfiles).AppendLine();
sb.AppendFormat("{0} reserved files", homeblock.resfiles).AppendLine();
if(homeblock.rvn > 0 && homeblock.setcount > 0 &&
if(homeblock.rvn > 0 && homeblock.setcount > 0 &&
StringHandlers.CToString(homeblock.strucname) != " ")
sb.AppendFormat("Volume is {0} of {1} in set \"{2}\".", homeblock.rvn, homeblock.setcount,
StringHandlers.SpacePaddedToString(homeblock.strucname, Encoding)).AppendLine();
@@ -206,20 +206,21 @@ namespace DiscImageChef.Filesystems
XmlFsType = new FileSystemType
{
Type = "FILES-11",
ClusterSize = homeblock.cluster * 512,
Clusters = (long)partition.Size / (homeblock.cluster * 512),
VolumeName = StringHandlers.SpacePaddedToString(homeblock.volname, Encoding),
Type = "FILES-11",
ClusterSize = homeblock.cluster * 512,
Clusters = (long)partition.Size / (homeblock.cluster * 512),
VolumeName = StringHandlers.SpacePaddedToString(homeblock.volname, Encoding),
VolumeSerial = $"{homeblock.serialnum:X8}"
};
if(homeblock.credate > 0)
{
XmlFsType.CreationDate = DateHandlers.VmsToDateTime(homeblock.credate);
XmlFsType.CreationDate = DateHandlers.VmsToDateTime(homeblock.credate);
XmlFsType.CreationDateSpecified = true;
}
if(homeblock.revdate > 0)
{
XmlFsType.ModificationDate = DateHandlers.VmsToDateTime(homeblock.revdate);
XmlFsType.ModificationDate = DateHandlers.VmsToDateTime(homeblock.revdate);
XmlFsType.ModificationDateSpecified = true;
}
@@ -290,9 +291,11 @@ namespace DiscImageChef.Filesystems
/// <summary>0x058, Last modification date</summary>
public ulong revdate;
/// <summary>0x060, Minimum security class, 20 bytes</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)] public byte[] min_class;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
public byte[] min_class;
/// <summary>0x074, Maximum security class, 20 bytes</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)] public byte[] max_class;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
public byte[] max_class;
/// <summary>0x088, File lookup table FID</summary>
public ushort filetab_fid1;
/// <summary>0x08A, File lookup table FID</summary>
@@ -306,17 +309,22 @@ namespace DiscImageChef.Filesystems
/// <summary>0x092, Volume copy date (??)</summary>
public ulong copydate;
/// <summary>0x09A, 302 bytes</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 302)] public byte[] reserved1;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 302)]
public byte[] reserved1;
/// <summary>0x1C8, Physical drive serial number</summary>
public uint serialnum;
/// <summary>0x1CC, Name of the volume set, 12 bytes</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)] public byte[] strucname;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)]
public byte[] strucname;
/// <summary>0x1D8, Volume label, 12 bytes</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)] public byte[] volname;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)]
public byte[] volname;
/// <summary>0x1E4, Name of the volume owner, 12 bytes</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)] public byte[] ownername;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)]
public byte[] ownername;
/// <summary>0x1F0, ODS-2 defines it as "DECFILE11B", 12 bytes</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)] public byte[] format;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)]
public byte[] format;
/// <summary>0x1FC, Reserved</summary>
public ushort reserved2;
/// <summary>0x1FE, Checksum of preceding 255 words (16 bit units)</summary>

View File

@@ -42,9 +42,9 @@ namespace DiscImageChef.Filesystems
public class OperaFS : IFilesystem
{
public FileSystemType XmlFsType { get; private set; }
public Encoding Encoding { get; private set; }
public string Name => "Opera Filesystem Plugin";
public Guid Id => new Guid("0ec84ec7-eae6-4196-83fe-943b3fe46dbd");
public Encoding Encoding { get; private set; }
public string Name => "Opera Filesystem Plugin";
public Guid Id => new Guid("0ec84ec7-eae6-4196-83fe-943b3fe46dbd");
public bool Identify(IMediaImage imagePlugin, Partition partition)
{
@@ -64,10 +64,10 @@ namespace DiscImageChef.Filesystems
}
public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
Encoding encoding)
Encoding encoding)
{
// TODO: Find correct default encoding
Encoding = Encoding.ASCII;
Encoding = Encoding.ASCII;
information = "";
StringBuilder superBlockMetadata = new StringBuilder();
@@ -82,12 +82,11 @@ namespace DiscImageChef.Filesystems
superBlockMetadata.AppendFormat("Opera filesystem disc.").AppendLine();
if(!string.IsNullOrEmpty(StringHandlers.CToString(sb.volume_label, Encoding)))
superBlockMetadata
.AppendFormat("Volume label: {0}", StringHandlers.CToString(sb.volume_label, Encoding))
.AppendLine();
.AppendFormat("Volume label: {0}", StringHandlers.CToString(sb.volume_label, Encoding)).AppendLine();
if(!string.IsNullOrEmpty(StringHandlers.CToString(sb.volume_comment, Encoding)))
superBlockMetadata
.AppendFormat("Volume comment: {0}", StringHandlers.CToString(sb.volume_comment, Encoding))
.AppendLine();
.AppendFormat("Volume comment: {0}", StringHandlers.CToString(sb.volume_comment, Encoding))
.AppendLine();
superBlockMetadata.AppendFormat("Volume identifier: 0x{0:X8}", sb.volume_id).AppendLine();
superBlockMetadata.AppendFormat("Block size: {0} bytes", sb.block_size).AppendLine();
if(imagePlugin.Info.SectorSize == 2336 || imagePlugin.Info.SectorSize == 2352 ||
@@ -95,20 +94,21 @@ namespace DiscImageChef.Filesystems
{
if(sb.block_size != 2048)
superBlockMetadata
.AppendFormat("WARNING: Filesystem indicates {0} bytes/block while device indicates {1} bytes/block",
sb.block_size, 2048);
.AppendFormat("WARNING: Filesystem indicates {0} bytes/block while device indicates {1} bytes/block",
sb.block_size, 2048);
}
else if(imagePlugin.Info.SectorSize != sb.block_size)
superBlockMetadata
.AppendFormat("WARNING: Filesystem indicates {0} bytes/block while device indicates {1} bytes/block",
sb.block_size, imagePlugin.Info.SectorSize);
.AppendFormat("WARNING: Filesystem indicates {0} bytes/block while device indicates {1} bytes/block",
sb.block_size, imagePlugin.Info.SectorSize);
superBlockMetadata
.AppendFormat("Volume size: {0} blocks, {1} bytes", sb.block_count, sb.block_size * sb.block_count)
.AppendLine();
.AppendFormat("Volume size: {0} blocks, {1} bytes", sb.block_count, sb.block_size * sb.block_count)
.AppendLine();
if((ulong)sb.block_count > imagePlugin.Info.Sectors)
superBlockMetadata
.AppendFormat("WARNING: Filesystem indicates {0} blocks while device indicates {1} blocks",
sb.block_count, imagePlugin.Info.Sectors);
.AppendFormat("WARNING: Filesystem indicates {0} blocks while device indicates {1} blocks",
sb.block_count, imagePlugin.Info.Sectors);
superBlockMetadata.AppendFormat("Root directory identifier: 0x{0:X8}", sb.root_dirid).AppendLine();
superBlockMetadata.AppendFormat("Root directory block size: {0} bytes", sb.rootdir_bsize).AppendLine();
superBlockMetadata.AppendFormat("Root directory size: {0} blocks, {1} bytes", sb.rootdir_blocks,
@@ -119,10 +119,10 @@ namespace DiscImageChef.Filesystems
XmlFsType = new FileSystemType
{
Type = "Opera",
VolumeName = StringHandlers.CToString(sb.volume_label, Encoding),
Type = "Opera",
VolumeName = StringHandlers.CToString(sb.volume_label, Encoding),
ClusterSize = sb.block_size,
Clusters = sb.block_count
Clusters = sb.block_count
};
}
@@ -132,15 +132,18 @@ namespace DiscImageChef.Filesystems
/// <summary>0x000, Record type, must be 1</summary>
public byte record_type;
/// <summary>0x001, 5 bytes, "ZZZZZ"</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)] public byte[] sync_bytes;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
public byte[] sync_bytes;
/// <summary>0x006, Record version, must be 1</summary>
public byte record_version;
/// <summary>0x007, Volume flags</summary>
public byte volume_flags;
/// <summary>0x008, 32 bytes, volume comment</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] public byte[] volume_comment;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public byte[] volume_comment;
/// <summary>0x028, 32 bytes, volume label</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] public byte[] volume_label;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public byte[] volume_label;
/// <summary>0x048, Volume ID</summary>
public int volume_id;
/// <summary>0x04C, Block size in bytes</summary>

View File

@@ -41,16 +41,16 @@ namespace DiscImageChef.Filesystems
public class PCEnginePlugin : IFilesystem
{
public FileSystemType XmlFsType { get; private set; }
public Encoding Encoding { get; private set; }
public string Name => "PC Engine CD Plugin";
public Guid Id => new Guid("e5ee6d7c-90fa-49bd-ac89-14ef750b8af3");
public Encoding Encoding { get; private set; }
public string Name => "PC Engine CD Plugin";
public Guid Id => new Guid("e5ee6d7c-90fa-49bd-ac89-14ef750b8af3");
public bool Identify(IMediaImage imagePlugin, Partition partition)
{
if(2 + partition.Start >= partition.End) return false;
byte[] systemDescriptor = new byte[23];
byte[] sector = imagePlugin.ReadSector(1 + partition.Start);
byte[] sector = imagePlugin.ReadSector(1 + partition.Start);
Array.Copy(sector, 0x20, systemDescriptor, 0, 23);
@@ -58,14 +58,14 @@ namespace DiscImageChef.Filesystems
}
public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
Encoding encoding)
Encoding encoding)
{
Encoding = encoding ?? Encoding.GetEncoding("shift_jis");
Encoding = encoding ?? Encoding.GetEncoding("shift_jis");
information = "";
XmlFsType = new FileSystemType
{
Type = "PC Engine filesystem",
Clusters = (long)((partition.End - partition.Start + 1) / imagePlugin.Info.SectorSize * 2048),
Type = "PC Engine filesystem",
Clusters = (long)((partition.End - partition.Start + 1) / imagePlugin.Info.SectorSize * 2048),
ClusterSize = 2048
};
}

View File

@@ -79,28 +79,26 @@ namespace DiscImageChef.Filesystems
try
{
date = Encoding.GetString(header.date);
date = Encoding.GetString(header.date);
int year = int.Parse(date.Substring(0, 4));
int month = int.Parse(date.Substring(4, 2));
int day = int.Parse(date.Substring(6, 2));
dateTime = new DateTime(year, month, day);
dateTime = new DateTime(year, month, day);
}
catch { date = null; }
StringBuilder sb = new StringBuilder();
sb.AppendLine("PC-FX executable:");
sb.AppendFormat("Identifier: {0}", StringHandlers.CToString(header.signature, Encoding)).AppendLine();
sb.AppendFormat("Identifier: {0}", StringHandlers.CToString(header.signature, Encoding)).AppendLine();
sb.AppendFormat("Copyright: {0}", StringHandlers.CToString(header.copyright, Encoding)).AppendLine();
sb.AppendFormat("Title: {0}", StringHandlers.CToString(header.title, Encoding)).AppendLine();
sb.AppendFormat("Maker ID: {0}", StringHandlers.CToString(header.makerId, Encoding)).AppendLine();
sb.AppendFormat("Maker name: {0}", StringHandlers.CToString(header.makerName, Encoding)).AppendLine();
sb.AppendFormat("Volume number: {0}", header.volumeNumber).AppendLine();
sb.AppendFormat("Country code: {0}", header.country).AppendLine();
sb.AppendFormat("Version: {0}.{1}", header.minorVersion, header.majorVersion)
.AppendLine();
if(date != null) sb.AppendFormat("Dated {0}", dateTime).AppendLine();
sb.AppendFormat("Load {0} sectors from sector {1}", header.loadCount, header.loadOffset)
.AppendLine();
sb.AppendFormat("Country code: {0}", header.country).AppendLine();
sb.AppendFormat("Version: {0}.{1}", header.minorVersion, header.majorVersion).AppendLine();
if(date != null) sb.AppendFormat("Dated {0}", dateTime).AppendLine();
sb.AppendFormat("Load {0} sectors from sector {1}", header.loadCount, header.loadOffset).AppendLine();
sb.AppendFormat("Load at 0x{0:X8} and jump to 0x{1:X8}", header.loadAddress, header.entryPoint)
.AppendLine();
@@ -115,7 +113,7 @@ namespace DiscImageChef.Filesystems
CreationDate = dateTime,
CreationDateSpecified = date != null,
PublisherIdentifier = StringHandlers.CToString(header.makerName, Encoding),
VolumeName = StringHandlers.CToString(header.title, Encoding),
VolumeName = StringHandlers.CToString(header.title, Encoding),
SystemIdentifier = "PC-FX"
};
}
@@ -131,10 +129,10 @@ namespace DiscImageChef.Filesystems
public byte[] unknown;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public byte[] title;
public uint loadOffset;
public uint loadCount;
public uint loadAddress;
public uint entryPoint;
public uint loadOffset;
public uint loadCount;
public uint loadAddress;
public uint entryPoint;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public byte[] makerId;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 60)]

View File

@@ -63,9 +63,9 @@ namespace DiscImageChef.Filesystems
const uint MUPFS_DISK = 0x6D755046;
public FileSystemType XmlFsType { get; private set; }
public Encoding Encoding { get; private set; }
public string Name => "Professional File System";
public Guid Id => new Guid("68DE769E-D957-406A-8AE4-3781CA8CDA77");
public Encoding Encoding { get; private set; }
public string Name => "Professional File System";
public Guid Id => new Guid("68DE769E-D957-406A-8AE4-3781CA8CDA77");
public bool Identify(IMediaImage imagePlugin, Partition partition)
{
@@ -82,11 +82,11 @@ namespace DiscImageChef.Filesystems
}
public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
Encoding encoding)
Encoding encoding)
{
Encoding = encoding ?? Encoding.GetEncoding("iso-8859-1");
byte[] rootBlockSector = imagePlugin.ReadSector(2 + partition.Start);
RootBlock rootBlock = BigEndianMarshal.ByteArrayToStructureBigEndian<RootBlock>(rootBlockSector);
byte[] rootBlockSector = imagePlugin.ReadSector(2 + partition.Start);
RootBlock rootBlock = BigEndianMarshal.ByteArrayToStructureBigEndian<RootBlock>(rootBlockSector);
StringBuilder sbInformation = new StringBuilder();
XmlFsType = new FileSystemType();
@@ -130,11 +130,11 @@ namespace DiscImageChef.Filesystems
XmlFsType.CreationDate =
DateHandlers.AmigaToDateTime(rootBlock.creationday, rootBlock.creationminute, rootBlock.creationtick);
XmlFsType.CreationDateSpecified = true;
XmlFsType.FreeClusters = rootBlock.blocksfree;
XmlFsType.FreeClusters = rootBlock.blocksfree;
XmlFsType.FreeClustersSpecified = true;
XmlFsType.Clusters = rootBlock.diskSize;
XmlFsType.ClusterSize = (int)imagePlugin.Info.SectorSize;
XmlFsType.VolumeName = StringHandlers.PascalToString(rootBlock.diskname, Encoding);
XmlFsType.Clusters = rootBlock.diskSize;
XmlFsType.ClusterSize = (int)imagePlugin.Info.SectorSize;
XmlFsType.VolumeName = StringHandlers.PascalToString(rootBlock.diskname, Encoding);
}
/// <summary>
@@ -187,7 +187,8 @@ namespace DiscImageChef.Filesystems
/// <summary>
/// Volume label (Pascal string)
/// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] public byte[] diskname;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public byte[] diskname;
/// <summary>
/// Last reserved block
/// </summary>

View File

@@ -57,7 +57,7 @@ namespace DiscImageChef.Filesystems
/// <summary>
/// A file that occupies between 257 and 32768 blocks
/// </summary>
const byte TREE_FILE_TYPE = 0x03;
const byte TREE_FILE_TYPE = 0x03;
const byte PASCAL_AREA_TYPE = 0x04;
const byte SUBDIRECTORY_TYPE = 0x0D;
const byte SUBDIRECTORY_HEADER_TYPE = 0x0E;
@@ -149,13 +149,13 @@ namespace DiscImageChef.Filesystems
DicConsole.DebugWriteLine("ProDOS plugin", "{0} <= ({1} - {2} + 1)? {3}", totalBlocks, partition.End,
partition.Start, totalBlocks <= partition.End - partition.Start + 1);
return totalBlocks <= partition.End - partition.Start + 1;
return totalBlocks <= partition.End - partition.Start + 1;
}
public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
Encoding encoding)
{
Encoding = encoding ?? new Apple2c();
Encoding = encoding ?? new Apple2c();
StringBuilder sbInformation = new StringBuilder();
uint multiplier = (uint)(imagePlugin.Info.SectorSize == 256 ? 2 : 1);
@@ -198,10 +198,9 @@ namespace DiscImageChef.Filesystems
};
rootDirectoryKeyBlock.header.storage_type =
(byte)((rootDirectoryKeyBlockBytes[0x04] & STORAGE_TYPE_MASK) >>
4);
(byte)((rootDirectoryKeyBlockBytes[0x04] & STORAGE_TYPE_MASK) >> 4);
rootDirectoryKeyBlock.header.name_length = (byte)(rootDirectoryKeyBlockBytes[0x04] & NAME_LENGTH_MASK);
byte[] temporal = new byte[rootDirectoryKeyBlock.header.name_length];
byte[] temporal = new byte[rootDirectoryKeyBlock.header.name_length];
Array.Copy(rootDirectoryKeyBlockBytes, 0x05, temporal, 0, rootDirectoryKeyBlock.header.name_length);
rootDirectoryKeyBlock.header.volume_name = Encoding.GetString(temporal);
rootDirectoryKeyBlock.header.reserved = BitConverter.ToUInt64(rootDirectoryKeyBlockBytes, 0x14);
@@ -212,13 +211,13 @@ namespace DiscImageChef.Filesystems
bool dateCorrect;
try
{
uint tempTimestamp = (uint)((tempTimestampLeft << 16) + tempTimestampRight);
int year = (int)((tempTimestamp & YEAR_MASK) >> 25);
int month = (int)((tempTimestamp & MONTH_MASK) >> 21);
int day = (int)((tempTimestamp & DAY_MASK) >> 16);
int hour = (int)((tempTimestamp & HOUR_MASK) >> 8);
int minute = (int)(tempTimestamp & MINUTE_MASK);
year += 1900;
uint tempTimestamp = (uint)((tempTimestampLeft << 16) + tempTimestampRight);
int year = (int)((tempTimestamp & YEAR_MASK) >> 25);
int month = (int)((tempTimestamp & MONTH_MASK) >> 21);
int day = (int)((tempTimestamp & DAY_MASK) >> 16);
int hour = (int)((tempTimestamp & HOUR_MASK) >> 8);
int minute = (int)(tempTimestamp & MINUTE_MASK);
year += 1900;
if(year < 1940) year += 100;
DicConsole.DebugWriteLine("ProDOS plugin", "temp_timestamp_left = 0x{0:X4}", tempTimestampLeft);
@@ -277,8 +276,7 @@ namespace DiscImageChef.Filesystems
.AppendLine();
sbInformation.AppendFormat("{0} files in root directory", rootDirectoryKeyBlock.header.file_count)
.AppendLine();
sbInformation.AppendFormat("{0} blocks in volume", rootDirectoryKeyBlock.header.total_blocks)
.AppendLine();
sbInformation.AppendFormat("{0} blocks in volume", rootDirectoryKeyBlock.header.total_blocks).AppendLine();
sbInformation.AppendFormat("Bitmap starts at block {0}", rootDirectoryKeyBlock.header.bit_map_pointer)
.AppendLine();

View File

@@ -46,9 +46,9 @@ namespace DiscImageChef.Filesystems
{0x2F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
public FileSystemType XmlFsType { get; private set; }
public Encoding Encoding { get; private set; }
public string Name => "QNX4 Plugin";
public Guid Id => new Guid("E73A63FA-B5B0-48BF-BF82-DA5F0A8170D2");
public Encoding Encoding { get; private set; }
public string Name => "QNX4 Plugin";
public Guid Id => new Guid("E73A63FA-B5B0-48BF-BF82-DA5F0A8170D2");
public bool Identify(IMediaImage imagePlugin, Partition partition)
{
@@ -71,22 +71,22 @@ namespace DiscImageChef.Filesystems
// Check extents are not past device
if(qnxSb.rootDir.di_first_xtnt.block + partition.Start >= partition.End ||
qnxSb.inode.di_first_xtnt.block + partition.Start >= partition.End ||
qnxSb.boot.di_first_xtnt.block + partition.Start >= partition.End ||
qnxSb.inode.di_first_xtnt.block + partition.Start >= partition.End ||
qnxSb.boot.di_first_xtnt.block + partition.Start >= partition.End ||
qnxSb.altBoot.di_first_xtnt.block + partition.Start >= partition.End) return false;
// Check inodes are in use
if((qnxSb.rootDir.di_status & 0x01) != 0x01 || (qnxSb.inode.di_status & 0x01) != 0x01 ||
(qnxSb.boot.di_status & 0x01) != 0x01) return false;
(qnxSb.boot.di_status & 0x01) != 0x01) return false;
// All hail filesystems without identification marks
return true;
}
public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
Encoding encoding)
Encoding encoding)
{
Encoding = encoding ?? Encoding.GetEncoding("iso-8859-15");
Encoding = encoding ?? Encoding.GetEncoding("iso-8859-15");
information = "";
byte[] sector = imagePlugin.ReadSector(partition.Start + 1);
if(sector.Length < 512) return;
@@ -176,12 +176,12 @@ namespace DiscImageChef.Filesystems
XmlFsType = new FileSystemType
{
Type = "QNX4 filesystem",
Clusters = (long)partition.Length,
ClusterSize = 512,
CreationDate = DateHandlers.UnixUnsignedToDateTime(qnxSb.rootDir.di_ftime),
CreationDateSpecified = true,
ModificationDate = DateHandlers.UnixUnsignedToDateTime(qnxSb.rootDir.di_mtime),
Type = "QNX4 filesystem",
Clusters = (long)partition.Length,
ClusterSize = 512,
CreationDate = DateHandlers.UnixUnsignedToDateTime(qnxSb.rootDir.di_ftime),
CreationDateSpecified = true,
ModificationDate = DateHandlers.UnixUnsignedToDateTime(qnxSb.rootDir.di_mtime),
ModificationDateSpecified = true
};
XmlFsType.Bootable |= qnxSb.boot.di_size != 0 || qnxSb.altBoot.di_size != 0;
@@ -196,31 +196,34 @@ namespace DiscImageChef.Filesystems
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct QNX4_Inode
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public byte[] di_fname;
public uint di_size;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[] di_fname;
public uint di_size;
public QNX4_Extent di_first_xtnt;
public uint di_xblk;
public uint di_ftime;
public uint di_mtime;
public uint di_atime;
public uint di_ctime;
public ushort di_num_xtnts;
public ushort di_mode;
public ushort di_uid;
public ushort di_gid;
public ushort di_nlink;
public uint di_zero;
public byte di_type;
public byte di_status;
public uint di_xblk;
public uint di_ftime;
public uint di_mtime;
public uint di_atime;
public uint di_ctime;
public ushort di_num_xtnts;
public ushort di_mode;
public ushort di_uid;
public ushort di_gid;
public ushort di_nlink;
public uint di_zero;
public byte di_type;
public byte di_status;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct QNX4_LinkInfo
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 48)] public byte[] dl_fname;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 48)]
public byte[] dl_fname;
public uint dl_inode_blk;
public byte dl_inode_ndx;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)] public byte[] dl_spare;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
public byte[] dl_spare;
public byte dl_status;
}
@@ -230,10 +233,13 @@ namespace DiscImageChef.Filesystems
public uint next_xblk;
public uint prev_xblk;
public byte num_xtnts;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] public byte[] spare;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public byte[] spare;
public uint num_blocks;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 60)] public QNX4_Extent[] xtnts;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] public byte[] signature;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 60)]
public QNX4_Extent[] xtnts;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public byte[] signature;
public QNX4_Extent first_xtnt;
}

View File

@@ -43,32 +43,32 @@ namespace DiscImageChef.Filesystems
{
const uint QNX6_SUPER_BLOCK_SIZE = 0x1000;
const uint QNX6_BOOT_BLOCKS_SIZE = 0x2000;
const uint QNX6_MAGIC = 0x68191122;
const uint QNX6_MAGIC = 0x68191122;
public FileSystemType XmlFsType { get; private set; }
public Encoding Encoding { get; private set; }
public string Name => "QNX6 Plugin";
public Guid Id => new Guid("3E610EA2-4D08-4D70-8947-830CD4C74FC0");
public Encoding Encoding { get; private set; }
public string Name => "QNX6 Plugin";
public Guid Id => new Guid("3E610EA2-4D08-4D70-8947-830CD4C74FC0");
public bool Identify(IMediaImage imagePlugin, Partition partition)
{
uint sectors = QNX6_SUPER_BLOCK_SIZE / imagePlugin.Info.SectorSize;
uint sectors = QNX6_SUPER_BLOCK_SIZE / imagePlugin.Info.SectorSize;
uint bootSectors = QNX6_BOOT_BLOCKS_SIZE / imagePlugin.Info.SectorSize;
if(partition.Start + bootSectors + sectors >= partition.End) return false;
byte[] audiSector = imagePlugin.ReadSectors(partition.Start, sectors);
byte[] sector = imagePlugin.ReadSectors(partition.Start + bootSectors, sectors);
byte[] audiSector = imagePlugin.ReadSectors(partition.Start, sectors);
byte[] sector = imagePlugin.ReadSectors(partition.Start + bootSectors, sectors);
if(sector.Length < QNX6_SUPER_BLOCK_SIZE) return false;
QNX6_AudiSuperBlock audiSb = new QNX6_AudiSuperBlock();
IntPtr audiPtr = Marshal.AllocHGlobal(Marshal.SizeOf(audiSb));
QNX6_AudiSuperBlock audiSb = new QNX6_AudiSuperBlock();
IntPtr audiPtr = Marshal.AllocHGlobal(Marshal.SizeOf(audiSb));
Marshal.Copy(audiSector, 0, audiPtr, Marshal.SizeOf(audiSb));
audiSb = (QNX6_AudiSuperBlock)Marshal.PtrToStructure(audiPtr, typeof(QNX6_AudiSuperBlock));
Marshal.FreeHGlobal(audiPtr);
QNX6_SuperBlock qnxSb = new QNX6_SuperBlock();
IntPtr sbPtr = Marshal.AllocHGlobal(Marshal.SizeOf(qnxSb));
IntPtr sbPtr = Marshal.AllocHGlobal(Marshal.SizeOf(qnxSb));
Marshal.Copy(sector, 0, sbPtr, Marshal.SizeOf(qnxSb));
qnxSb = (QNX6_SuperBlock)Marshal.PtrToStructure(sbPtr, typeof(QNX6_SuperBlock));
Marshal.FreeHGlobal(sbPtr);
@@ -77,26 +77,26 @@ namespace DiscImageChef.Filesystems
}
public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
Encoding encoding)
Encoding encoding)
{
Encoding = encoding ?? Encoding.GetEncoding("iso-8859-15");
Encoding = encoding ?? Encoding.GetEncoding("iso-8859-15");
information = "";
StringBuilder sb = new StringBuilder();
uint sectors = QNX6_SUPER_BLOCK_SIZE / imagePlugin.Info.SectorSize;
uint bootSectors = QNX6_BOOT_BLOCKS_SIZE / imagePlugin.Info.SectorSize;
StringBuilder sb = new StringBuilder();
uint sectors = QNX6_SUPER_BLOCK_SIZE / imagePlugin.Info.SectorSize;
uint bootSectors = QNX6_BOOT_BLOCKS_SIZE / imagePlugin.Info.SectorSize;
byte[] audiSector = imagePlugin.ReadSectors(partition.Start, sectors);
byte[] sector = imagePlugin.ReadSectors(partition.Start + bootSectors, sectors);
byte[] audiSector = imagePlugin.ReadSectors(partition.Start, sectors);
byte[] sector = imagePlugin.ReadSectors(partition.Start + bootSectors, sectors);
if(sector.Length < QNX6_SUPER_BLOCK_SIZE) return;
QNX6_AudiSuperBlock audiSb = new QNX6_AudiSuperBlock();
IntPtr audiPtr = Marshal.AllocHGlobal(Marshal.SizeOf(audiSb));
QNX6_AudiSuperBlock audiSb = new QNX6_AudiSuperBlock();
IntPtr audiPtr = Marshal.AllocHGlobal(Marshal.SizeOf(audiSb));
Marshal.Copy(audiSector, 0, audiPtr, Marshal.SizeOf(audiSb));
audiSb = (QNX6_AudiSuperBlock)Marshal.PtrToStructure(audiPtr, typeof(QNX6_AudiSuperBlock));
Marshal.FreeHGlobal(audiPtr);
QNX6_SuperBlock qnxSb = new QNX6_SuperBlock();
IntPtr sbPtr = Marshal.AllocHGlobal(Marshal.SizeOf(qnxSb));
IntPtr sbPtr = Marshal.AllocHGlobal(Marshal.SizeOf(qnxSb));
Marshal.Copy(sector, 0, sbPtr, Marshal.SizeOf(qnxSb));
qnxSb = (QNX6_SuperBlock)Marshal.PtrToStructure(sbPtr, typeof(QNX6_SuperBlock));
Marshal.FreeHGlobal(sbPtr);
@@ -112,19 +112,19 @@ namespace DiscImageChef.Filesystems
sb.AppendFormat("{0} inodes free of {1}", audiSb.freeInodes, audiSb.numInodes).AppendLine();
sb.AppendFormat("{0} blocks ({1} bytes) free of {2} ({3} bytes)", audiSb.freeBlocks,
audiSb.freeBlocks * audiSb.blockSize, audiSb.numBlocks,
audiSb.numBlocks * audiSb.blockSize).AppendLine();
audiSb.numBlocks * audiSb.blockSize).AppendLine();
XmlFsType = new FileSystemType
{
Type = "QNX6 (Audi) filesystem",
Clusters = audiSb.numBlocks,
ClusterSize = (int)audiSb.blockSize,
Bootable = true,
Files = audiSb.numInodes - audiSb.freeInodes,
FilesSpecified = true,
FreeClusters = audiSb.freeBlocks,
Type = "QNX6 (Audi) filesystem",
Clusters = audiSb.numBlocks,
ClusterSize = (int)audiSb.blockSize,
Bootable = true,
Files = audiSb.numInodes - audiSb.freeInodes,
FilesSpecified = true,
FreeClusters = audiSb.freeBlocks,
FreeClustersSpecified = true,
VolumeSerial = $"{audiSb.serial:X16}"
VolumeSerial = $"{audiSb.serial:X16}"
};
//xmlFSType.VolumeName = CurrentEncoding.GetString(audiSb.id);
@@ -149,18 +149,18 @@ namespace DiscImageChef.Filesystems
XmlFsType = new FileSystemType
{
Type = "QNX6 filesystem",
Clusters = qnxSb.numBlocks,
ClusterSize = (int)qnxSb.blockSize,
Bootable = true,
Files = qnxSb.numInodes - qnxSb.freeInodes,
FilesSpecified = true,
FreeClusters = qnxSb.freeBlocks,
FreeClustersSpecified = true,
VolumeSerial = $"{qnxSb.serial:X16}",
CreationDate = DateHandlers.UnixUnsignedToDateTime(qnxSb.ctime),
CreationDateSpecified = true,
ModificationDate = DateHandlers.UnixUnsignedToDateTime(qnxSb.atime),
Type = "QNX6 filesystem",
Clusters = qnxSb.numBlocks,
ClusterSize = (int)qnxSb.blockSize,
Bootable = true,
Files = qnxSb.numInodes - qnxSb.freeInodes,
FilesSpecified = true,
FreeClusters = qnxSb.freeBlocks,
FreeClustersSpecified = true,
VolumeSerial = $"{qnxSb.serial:X16}",
CreationDate = DateHandlers.UnixUnsignedToDateTime(qnxSb.ctime),
CreationDateSpecified = true,
ModificationDate = DateHandlers.UnixUnsignedToDateTime(qnxSb.atime),
ModificationDateSpecified = true
};
//xmlFSType.VolumeName = CurrentEncoding.GetString(qnxSb.volumeid);
@@ -172,30 +172,33 @@ namespace DiscImageChef.Filesystems
struct QNX6_RootNode
{
public ulong size;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public uint[] pointers;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public uint[] pointers;
public byte levels;
public byte mode;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)] public byte[] spare;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
public byte[] spare;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct QNX6_SuperBlock
{
public uint magic;
public uint checksum;
public ulong serial;
public uint ctime;
public uint atime;
public uint flags;
public uint magic;
public uint checksum;
public ulong serial;
public uint ctime;
public uint atime;
public uint flags;
public ushort version1;
public ushort version2;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public byte[] volumeid;
public uint blockSize;
public uint numInodes;
public uint freeInodes;
public uint numBlocks;
public uint freeBlocks;
public uint allocationGroup;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[] volumeid;
public uint blockSize;
public uint numInodes;
public uint freeInodes;
public uint numBlocks;
public uint freeBlocks;
public uint allocationGroup;
public QNX6_RootNode inode;
public QNX6_RootNode bitmap;
public QNX6_RootNode longfile;
@@ -205,17 +208,19 @@ namespace DiscImageChef.Filesystems
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct QNX6_AudiSuperBlock
{
public uint magic;
public uint checksum;
public uint magic;
public uint checksum;
public ulong serial;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)] public byte[] spare1;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)] public byte[] id;
public uint blockSize;
public uint numInodes;
public uint freeInodes;
public uint numBlocks;
public uint freeBlocks;
public uint spare2;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)]
public byte[] spare1;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)]
public byte[] id;
public uint blockSize;
public uint numInodes;
public uint freeInodes;
public uint numBlocks;
public uint freeBlocks;
public uint spare2;
public QNX6_RootNode inode;
public QNX6_RootNode bitmap;
public QNX6_RootNode longfile;

View File

@@ -60,8 +60,8 @@ namespace DiscImageChef.Filesystems
// I've read OS-9/Apple2 has it on sector 15
foreach(int i in new[] {0, 4, 15})
{
ulong location = (ulong)i;
RBF_IdSector rbfSb = new RBF_IdSector();
ulong location = (ulong)i;
RBF_IdSector rbfSb = new RBF_IdSector();
uint sbSize = (uint)(Marshal.SizeOf(rbfSb) / imagePlugin.Info.SectorSize);
if(Marshal.SizeOf(rbfSb) % imagePlugin.Info.SectorSize != 0) sbSize++;
@@ -98,7 +98,7 @@ namespace DiscImageChef.Filesystems
foreach(int i in new[] {0, 4, 15})
{
ulong location = (ulong)i;
uint sbSize = (uint)(Marshal.SizeOf(rbfSb) / imagePlugin.Info.SectorSize);
uint sbSize = (uint)(Marshal.SizeOf(rbfSb) / imagePlugin.Info.SectorSize);
if(Marshal.SizeOf(rbfSb) % imagePlugin.Info.SectorSize != 0) sbSize++;
byte[] sector = imagePlugin.ReadSectors(partition.Start + location, sbSize);

View File

@@ -46,9 +46,9 @@ namespace DiscImageChef.Filesystems
public class RT11 : IFilesystem
{
public FileSystemType XmlFsType { get; private set; }
public Encoding Encoding { get; private set; }
public string Name => "RT-11 file system";
public Guid Id => new Guid("DB3E2F98-8F98-463C-8126-E937843DA024");
public Encoding Encoding { get; private set; }
public string Name => "RT-11 file system";
public Guid Id => new Guid("DB3E2F98-8F98-463C-8126-E937843DA024");
public bool Identify(IMediaImage imagePlugin, Partition partition)
{
@@ -56,7 +56,7 @@ namespace DiscImageChef.Filesystems
if(imagePlugin.Info.SectorSize < 512) return false;
byte[] magicB = new byte[12];
byte[] magicB = new byte[12];
byte[] hbSector = imagePlugin.ReadSector(1 + partition.Start);
Array.Copy(hbSector, 0x1F0, magicB, 0, 12);
@@ -66,9 +66,9 @@ namespace DiscImageChef.Filesystems
}
public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
Encoding encoding)
Encoding encoding)
{
Encoding = new Radix50();
Encoding = new Radix50();
information = "";
StringBuilder sb = new StringBuilder();
@@ -89,7 +89,7 @@ namespace DiscImageChef.Filesystems
* SOB R2, 10$
* MOV 1,@R0
*/
ushort check = 0;
ushort check = 0;
for(int i = 0; i < 512; i += 2) check += BitConverter.ToUInt16(hbSector, i);
sb.AppendFormat("Volume format is {0}",
@@ -105,11 +105,11 @@ namespace DiscImageChef.Filesystems
XmlFsType = new FileSystemType
{
Type = "RT-11",
Type = "RT-11",
ClusterSize = homeblock.cluster * 512,
Clusters = homeblock.cluster,
VolumeName = StringHandlers.SpacePaddedToString(homeblock.volname, Encoding),
Bootable = !ArrayHelpers.ArrayIsNullOrEmpty(bootBlock)
Clusters = homeblock.cluster,
VolumeName = StringHandlers.SpacePaddedToString(homeblock.volname, Encoding),
Bootable = !ArrayHelpers.ArrayIsNullOrEmpty(bootBlock)
};
information = sb.ToString();
@@ -119,32 +119,44 @@ namespace DiscImageChef.Filesystems
struct RT11HomeBlock
{
/// <summary>Bad block replacement table</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 130)] public byte[] badBlockTable;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 130)]
public byte[] badBlockTable;
/// <summary>Unused</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] public byte[] unused;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public byte[] unused;
/// <summary>INITIALIZE/RESTORE data area</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 38)] public byte[] initArea;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 38)]
public byte[] initArea;
/// <summary>BUP information area</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 18)] public byte[] bupInformation;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 18)]
public byte[] bupInformation;
/// <summary>Empty</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 260)] public byte[] empty;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 260)]
public byte[] empty;
/// <summary>Reserved</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] public byte[] reserved1;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public byte[] reserved1;
/// <summary>Reserved</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] public byte[] reserved2;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 14)] public byte[] empty2;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public byte[] reserved2;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 14)]
public byte[] empty2;
/// <summary>Cluster size</summary>
public ushort cluster;
/// <summary>Block of the first directory segment</summary>
public ushort rootBlock;
/// <summary>"V3A" in Radix-50</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] public byte[] systemVersion;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public byte[] systemVersion;
/// <summary>Name of the volume, 12 bytes</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)] public byte[] volname;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)]
public byte[] volname;
/// <summary>Name of the volume owner, 12 bytes</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)] public byte[] ownername;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)]
public byte[] ownername;
/// <summary>RT11 defines it as "DECRT11A ", 12 bytes</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)] public byte[] format;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)]
public byte[] format;
/// <summary>Unused</summary>
public ushort unused2;
/// <summary>Checksum of preceding 255 words (16 bit units)</summary>

View File

@@ -55,7 +55,7 @@ namespace DiscImageChef.Filesystems
RefsVolumeHeader refsVhdr = new RefsVolumeHeader();
uint sbSize = (uint)(Marshal.SizeOf(refsVhdr) / imagePlugin.Info.SectorSize);
if(Marshal.SizeOf(refsVhdr) % imagePlugin.Info.SectorSize != 0) sbSize++;
if(Marshal.SizeOf(refsVhdr) % imagePlugin.Info.SectorSize != 0) sbSize++;
if(partition.Start + sbSize >= partition.End) return false;
@@ -74,12 +74,12 @@ namespace DiscImageChef.Filesystems
public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
Encoding encoding)
{
Encoding = Encoding.UTF8;
information = "";
Encoding = Encoding.UTF8;
information = "";
RefsVolumeHeader refsVhdr = new RefsVolumeHeader();
uint sbSize = (uint)(Marshal.SizeOf(refsVhdr) / imagePlugin.Info.SectorSize);
if(Marshal.SizeOf(refsVhdr) % imagePlugin.Info.SectorSize != 0) sbSize++;
if(Marshal.SizeOf(refsVhdr) % imagePlugin.Info.SectorSize != 0) sbSize++;
if(partition.Start + sbSize >= partition.End) return;

View File

@@ -49,15 +49,15 @@ namespace DiscImageChef.Filesystems
readonly byte[] reiserJr_magic = {0x52, 0x65, 0x49, 0x73, 0x45, 0x72, 0x33, 0x46, 0x73, 0x00};
public FileSystemType XmlFsType { get; private set; }
public Encoding Encoding { get; private set; }
public string Name => "Reiser Filesystem Plugin";
public Guid Id => new Guid("1D8CD8B8-27E6-410F-9973-D16409225FBA");
public Encoding Encoding { get; private set; }
public string Name => "Reiser Filesystem Plugin";
public Guid Id => new Guid("1D8CD8B8-27E6-410F-9973-D16409225FBA");
public bool Identify(IMediaImage imagePlugin, Partition partition)
{
if(imagePlugin.Info.SectorSize < 512) return false;
uint sbAddr = REISER_SUPER_OFFSET / imagePlugin.Info.SectorSize;
uint sbAddr = REISER_SUPER_OFFSET / imagePlugin.Info.SectorSize;
if(sbAddr == 0) sbAddr = 1;
Reiser_Superblock reiserSb = new Reiser_Superblock();
@@ -80,13 +80,13 @@ namespace DiscImageChef.Filesystems
}
public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
Encoding encoding)
Encoding encoding)
{
Encoding = encoding ?? Encoding.GetEncoding("iso-8859-15");
Encoding = encoding ?? Encoding.GetEncoding("iso-8859-15");
information = "";
if(imagePlugin.Info.SectorSize < 512) return;
uint sbAddr = REISER_SUPER_OFFSET / imagePlugin.Info.SectorSize;
uint sbAddr = REISER_SUPER_OFFSET / imagePlugin.Info.SectorSize;
if(sbAddr == 0) sbAddr = 1;
Reiser_Superblock reiserSb = new Reiser_Superblock();
@@ -126,17 +126,17 @@ namespace DiscImageChef.Filesystems
information = sb.ToString();
XmlFsType = new FileSystemType();
if(reiser35_magic.SequenceEqual(reiserSb.magic)) XmlFsType.Type = "Reiser 3.5 filesystem";
if(reiser35_magic.SequenceEqual(reiserSb.magic)) XmlFsType.Type = "Reiser 3.5 filesystem";
else if(reiser36_magic.SequenceEqual(reiserSb.magic)) XmlFsType.Type = "Reiser 3.6 filesystem";
else if(reiserJr_magic.SequenceEqual(reiserSb.magic)) XmlFsType.Type = "Reiser Jr. filesystem";
XmlFsType.ClusterSize = reiserSb.blocksize;
XmlFsType.Clusters = reiserSb.block_count;
XmlFsType.FreeClusters = reiserSb.free_blocks;
XmlFsType.ClusterSize = reiserSb.blocksize;
XmlFsType.Clusters = reiserSb.block_count;
XmlFsType.FreeClusters = reiserSb.free_blocks;
XmlFsType.FreeClustersSpecified = true;
XmlFsType.Dirty = reiserSb.umount_state == 2;
XmlFsType.Dirty = reiserSb.umount_state == 2;
if(reiserSb.version < 2) return;
XmlFsType.VolumeName = Encoding.GetString(reiserSb.label);
XmlFsType.VolumeName = Encoding.GetString(reiserSb.label);
XmlFsType.VolumeSerial = reiserSb.uuid.ToString();
}
@@ -156,30 +156,33 @@ namespace DiscImageChef.Filesystems
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct Reiser_Superblock
{
public uint block_count;
public uint free_blocks;
public uint root_block;
public uint block_count;
public uint free_blocks;
public uint root_block;
public ReiserJournalParams journal;
public ushort blocksize;
public ushort oid_maxsize;
public ushort oid_cursize;
public ushort umount_state;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)] public byte[] magic;
public ushort blocksize;
public ushort oid_maxsize;
public ushort oid_cursize;
public ushort umount_state;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
public byte[] magic;
public ushort fs_state;
public uint hash_function_code;
public uint hash_function_code;
public ushort tree_height;
public ushort bmap_nr;
public ushort version;
public ushort reserved_for_journal;
public uint inode_generation;
public uint flags;
public Guid uuid;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public byte[] label;
public uint inode_generation;
public uint flags;
public Guid uuid;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[] label;
public ushort mnt_count;
public ushort max_mnt_count;
public uint last_check;
public uint check_interval;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 76)] public byte[] unused;
public uint last_check;
public uint check_interval;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 76)]
public byte[] unused;
}
}
}

View File

@@ -48,15 +48,15 @@ namespace DiscImageChef.Filesystems
{0x52, 0x65, 0x49, 0x73, 0x45, 0x72, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
public FileSystemType XmlFsType { get; private set; }
public Encoding Encoding { get; private set; }
public string Name => "Reiser4 Filesystem Plugin";
public Guid Id => new Guid("301F2D00-E8D5-4F04-934E-81DFB21D15BA");
public Encoding Encoding { get; private set; }
public string Name => "Reiser4 Filesystem Plugin";
public Guid Id => new Guid("301F2D00-E8D5-4F04-934E-81DFB21D15BA");
public bool Identify(IMediaImage imagePlugin, Partition partition)
{
if(imagePlugin.Info.SectorSize < 512) return false;
uint sbAddr = REISER4_SUPER_OFFSET / imagePlugin.Info.SectorSize;
uint sbAddr = REISER4_SUPER_OFFSET / imagePlugin.Info.SectorSize;
if(sbAddr == 0) sbAddr = 1;
Reiser4_Superblock reiserSb = new Reiser4_Superblock();
@@ -78,13 +78,13 @@ namespace DiscImageChef.Filesystems
}
public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
Encoding encoding)
Encoding encoding)
{
Encoding = encoding ?? Encoding.GetEncoding("iso-8859-15");
Encoding = encoding ?? Encoding.GetEncoding("iso-8859-15");
information = "";
if(imagePlugin.Info.SectorSize < 512) return;
uint sbAddr = REISER4_SUPER_OFFSET / imagePlugin.Info.SectorSize;
uint sbAddr = REISER4_SUPER_OFFSET / imagePlugin.Info.SectorSize;
if(sbAddr == 0) sbAddr = 1;
Reiser4_Superblock reiserSb = new Reiser4_Superblock();
@@ -114,10 +114,11 @@ namespace DiscImageChef.Filesystems
XmlFsType = new FileSystemType
{
Type = "Reiser 4 filesystem",
Type = "Reiser 4 filesystem",
ClusterSize = reiserSb.blocksize,
Clusters = (long)((partition.End - partition.Start) * imagePlugin.Info.SectorSize / reiserSb.blocksize),
VolumeName = StringHandlers.CToString(reiserSb.label, Encoding),
Clusters =
(long)((partition.End - partition.Start) * imagePlugin.Info.SectorSize / reiserSb.blocksize),
VolumeName = StringHandlers.CToString(reiserSb.label, Encoding),
VolumeSerial = reiserSb.uuid.ToString()
};
}
@@ -125,11 +126,13 @@ namespace DiscImageChef.Filesystems
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct Reiser4_Superblock
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public byte[] magic;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[] magic;
public ushort diskformat;
public ushort blocksize;
public Guid uuid;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public byte[] label;
public Guid uuid;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[] label;
}
}
}

View File

@@ -47,9 +47,9 @@ namespace DiscImageChef.Filesystems
const uint SFS2_MAGIC = 0x53465302;
public FileSystemType XmlFsType { get; private set; }
public Encoding Encoding { get; private set; }
public string Name => "SmartFileSystem";
public Guid Id => new Guid("26550C19-3671-4A2D-BC2F-F20CEB7F48DC");
public Encoding Encoding { get; private set; }
public string Name => "SmartFileSystem";
public Guid Id => new Guid("26550C19-3671-4A2D-BC2F-F20CEB7F48DC");
public bool Identify(IMediaImage imagePlugin, Partition partition)
{
@@ -65,11 +65,11 @@ namespace DiscImageChef.Filesystems
}
public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
Encoding encoding)
Encoding encoding)
{
Encoding = encoding ?? Encoding.GetEncoding("iso-8859-1");
byte[] rootBlockSector = imagePlugin.ReadSector(partition.Start);
RootBlock rootBlock = BigEndianMarshal.ByteArrayToStructureBigEndian<RootBlock>(rootBlockSector);
byte[] rootBlockSector = imagePlugin.ReadSector(partition.Start);
RootBlock rootBlock = BigEndianMarshal.ByteArrayToStructureBigEndian<RootBlock>(rootBlockSector);
StringBuilder sbInformation = new StringBuilder();
@@ -79,8 +79,8 @@ namespace DiscImageChef.Filesystems
sbInformation.AppendFormat("Volume starts on device byte {0} and ends on byte {1}", rootBlock.firstbyte,
rootBlock.lastbyte).AppendLine();
sbInformation
.AppendFormat("Volume has {0} blocks of {1} bytes each", rootBlock.totalblocks, rootBlock.blocksize)
.AppendLine();
.AppendFormat("Volume has {0} blocks of {1} bytes each", rootBlock.totalblocks, rootBlock.blocksize)
.AppendLine();
sbInformation.AppendFormat("Volume created on {0}",
DateHandlers.UnixUnsignedToDateTime(rootBlock.datecreated).AddYears(8))
.AppendLine();
@@ -100,11 +100,11 @@ namespace DiscImageChef.Filesystems
XmlFsType = new FileSystemType
{
CreationDate = DateHandlers.UnixUnsignedToDateTime(rootBlock.datecreated).AddYears(8),
CreationDate = DateHandlers.UnixUnsignedToDateTime(rootBlock.datecreated).AddYears(8),
CreationDateSpecified = true,
Clusters = rootBlock.totalblocks,
ClusterSize = (int)rootBlock.blocksize,
Type = "SmartFileSystem"
Clusters = rootBlock.totalblocks,
ClusterSize = (int)rootBlock.blocksize,
Type = "SmartFileSystem"
};
}
@@ -118,28 +118,32 @@ namespace DiscImageChef.Filesystems
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct RootBlock
{
public uint blockId;
public uint blockChecksum;
public uint blockSelfPointer;
public ushort version;
public ushort sequence;
public uint datecreated;
public uint blockId;
public uint blockChecksum;
public uint blockSelfPointer;
public ushort version;
public ushort sequence;
public uint datecreated;
public SFSFlags bits;
public byte padding1;
public ushort padding2;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] public uint[] reserved1;
public byte padding1;
public ushort padding2;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public uint[] reserved1;
public ulong firstbyte;
public ulong lastbyte;
public uint totalblocks;
public uint blocksize;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)] public uint[] reserved2;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] public uint[] reserved3;
public uint totalblocks;
public uint blocksize;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public uint[] reserved2;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public uint[] reserved3;
public uint bitmapbase;
public uint adminspacecontainer;
public uint rootobjectcontainer;
public uint extentbnoderoot;
public uint objectnoderoot;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] public uint[] reserved4;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public uint[] reserved4;
}
}
}

View File

@@ -43,9 +43,9 @@ namespace DiscImageChef.Filesystems
public class SolarFS : IFilesystem
{
public FileSystemType XmlFsType { get; private set; }
public Encoding Encoding { get; private set; }
public string Name => "Solar_OS filesystem";
public Guid Id => new Guid("EA3101C1-E777-4B4F-B5A3-8C57F50F6E65");
public Encoding Encoding { get; private set; }
public string Name => "Solar_OS filesystem";
public Guid Id => new Guid("EA3101C1-E777-4B4F-B5A3-8C57F50F6E65");
public bool Identify(IMediaImage imagePlugin, Partition partition)
{
@@ -63,32 +63,32 @@ namespace DiscImageChef.Filesystems
}
public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
Encoding encoding)
Encoding encoding)
{
Encoding = encoding ?? Encoding.GetEncoding("iso-8859-15");
Encoding = encoding ?? Encoding.GetEncoding("iso-8859-15");
information = "";
StringBuilder sb = new StringBuilder();
byte[] bpbSector = imagePlugin.ReadSector(0 + partition.Start);
StringBuilder sb = new StringBuilder();
byte[] bpbSector = imagePlugin.ReadSector(0 + partition.Start);
SolarOSParameterBlock bpb = new SolarOSParameterBlock
{
bps = BitConverter.ToUInt16(bpbSector, 0x0B),
root_ent = BitConverter.ToUInt16(bpbSector, 0x10),
sectors = BitConverter.ToUInt16(bpbSector, 0x12),
media = bpbSector[0x14],
spfat = BitConverter.ToUInt16(bpbSector, 0x15),
sptrk = BitConverter.ToUInt16(bpbSector, 0x17),
heads = BitConverter.ToUInt16(bpbSector, 0x19),
bps = BitConverter.ToUInt16(bpbSector, 0x0B),
root_ent = BitConverter.ToUInt16(bpbSector, 0x10),
sectors = BitConverter.ToUInt16(bpbSector, 0x12),
media = bpbSector[0x14],
spfat = BitConverter.ToUInt16(bpbSector, 0x15),
sptrk = BitConverter.ToUInt16(bpbSector, 0x17),
heads = BitConverter.ToUInt16(bpbSector, 0x19),
signature = bpbSector[0x25]
};
byte[] bpbStrings = new byte[8];
Array.Copy(bpbSector, 0x03, bpbStrings, 0, 8);
bpb.OEMName = StringHandlers.CToString(bpbStrings);
bpbStrings = new byte[8];
bpbStrings = new byte[8];
Array.Copy(bpbSector, 0x2A, bpbStrings, 0, 11);
bpb.vol_name = StringHandlers.CToString(bpbStrings, Encoding);
bpbStrings = new byte[8];
bpbStrings = new byte[8];
Array.Copy(bpbSector, 0x35, bpbStrings, 0, 8);
bpb.fs_type = StringHandlers.CToString(bpbStrings, Encoding);
@@ -103,23 +103,23 @@ namespace DiscImageChef.Filesystems
DicConsole.DebugWriteLine("SolarFS plugin", "BPB.x86_jump: 0x{0:X2}{1:X2}{2:X2}", bpb.x86_jump[0],
bpb.x86_jump[1], bpb.x86_jump[2]);
DicConsole.DebugWriteLine("SolarFS plugin", "BPB.OEMName: \"{0}\"", bpb.OEMName);
DicConsole.DebugWriteLine("SolarFS plugin", "BPB.bps: {0}", bpb.bps);
DicConsole.DebugWriteLine("SolarFS plugin", "BPB.unk1: 0x{0:X2}", bpb.unk1);
DicConsole.DebugWriteLine("SolarFS plugin", "BPB.unk2: 0x{0:X4}", bpb.unk2);
DicConsole.DebugWriteLine("SolarFS plugin", "BPB.root_ent: {0}", bpb.root_ent);
DicConsole.DebugWriteLine("SolarFS plugin", "BPB.sectors: {0}", bpb.sectors);
DicConsole.DebugWriteLine("SolarFS plugin", "BPB.media: 0x{0:X2}", bpb.media);
DicConsole.DebugWriteLine("SolarFS plugin", "BPB.spfat: {0}", bpb.spfat);
DicConsole.DebugWriteLine("SolarFS plugin", "BPB.sptrk: {0}", bpb.sptrk);
DicConsole.DebugWriteLine("SolarFS plugin", "BPB.heads: {0}", bpb.heads);
DicConsole.DebugWriteLine("SolarFS plugin", "BPB.bps: {0}", bpb.bps);
DicConsole.DebugWriteLine("SolarFS plugin", "BPB.unk1: 0x{0:X2}", bpb.unk1);
DicConsole.DebugWriteLine("SolarFS plugin", "BPB.unk2: 0x{0:X4}", bpb.unk2);
DicConsole.DebugWriteLine("SolarFS plugin", "BPB.root_ent: {0}", bpb.root_ent);
DicConsole.DebugWriteLine("SolarFS plugin", "BPB.sectors: {0}", bpb.sectors);
DicConsole.DebugWriteLine("SolarFS plugin", "BPB.media: 0x{0:X2}", bpb.media);
DicConsole.DebugWriteLine("SolarFS plugin", "BPB.spfat: {0}", bpb.spfat);
DicConsole.DebugWriteLine("SolarFS plugin", "BPB.sptrk: {0}", bpb.sptrk);
DicConsole.DebugWriteLine("SolarFS plugin", "BPB.heads: {0}", bpb.heads);
DicConsole.DebugWriteLine("SolarFS plugin",
"BPB.unk3: 0x{0:X2}{1:X2}{2:X2}{3:X2}{4:X2}{5:X2}{6:X2}{7:X2}{8:X2}{9:X2}",
bpb.unk3[0], bpb.unk3[1], bpb.unk3[2], bpb.unk3[3], bpb.unk3[4], bpb.unk3[5],
bpb.unk3[6], bpb.unk3[7], bpb.unk3[8], bpb.unk3[9]);
DicConsole.DebugWriteLine("SolarFS plugin", "BPB.signature: 0x{0:X2}", bpb.signature);
DicConsole.DebugWriteLine("SolarFS plugin", "BPB.unk4: 0x{0:X8}", bpb.unk4);
DicConsole.DebugWriteLine("SolarFS plugin", "BPB.vol_name: \"{0}\"", bpb.vol_name);
DicConsole.DebugWriteLine("SolarFS plugin", "BPB.fs_type: \"{0}\"", bpb.fs_type);
DicConsole.DebugWriteLine("SolarFS plugin", "BPB.unk4: 0x{0:X8}", bpb.unk4);
DicConsole.DebugWriteLine("SolarFS plugin", "BPB.vol_name: \"{0}\"", bpb.vol_name);
DicConsole.DebugWriteLine("SolarFS plugin", "BPB.fs_type: \"{0}\"", bpb.fs_type);
sb.AppendLine("Solar_OS filesystem");
sb.AppendFormat("Media descriptor: 0x{0:X2}", bpb.media).AppendLine();
@@ -129,13 +129,14 @@ namespace DiscImageChef.Filesystems
{
if(bpb.bps != imagePlugin.Info.SectorSize)
sb
.AppendFormat("WARNING: Filesystem describes a {0} bytes/sector, while device describes a {1} bytes/sector",
bpb.bps, 2048).AppendLine();
.AppendFormat("WARNING: Filesystem describes a {0} bytes/sector, while device describes a {1} bytes/sector",
bpb.bps, 2048).AppendLine();
}
else if(bpb.bps != imagePlugin.Info.SectorSize)
sb
.AppendFormat("WARNING: Filesystem describes a {0} bytes/sector, while device describes a {1} bytes/sector",
bpb.bps, imagePlugin.Info.SectorSize).AppendLine();
.AppendFormat("WARNING: Filesystem describes a {0} bytes/sector, while device describes a {1} bytes/sector",
bpb.bps, imagePlugin.Info.SectorSize).AppendLine();
sb.AppendFormat("{0} sectors on volume ({1} bytes)", bpb.sectors, bpb.sectors * bpb.bps).AppendLine();
if(bpb.sectors > imagePlugin.Info.Sectors)
sb.AppendFormat("WARNING: Filesystem describes a {0} sectors volume, bigger than device ({1} sectors)",
@@ -146,10 +147,10 @@ namespace DiscImageChef.Filesystems
XmlFsType = new FileSystemType
{
Type = "SolarFS",
Clusters = bpb.sectors,
Type = "SolarFS",
Clusters = bpb.sectors,
ClusterSize = bpb.bps,
VolumeName = bpb.vol_name
VolumeName = bpb.vol_name
};
information = sb.ToString();

View File

@@ -48,9 +48,9 @@ namespace DiscImageChef.Filesystems
const uint SQUASH_CIGAM = 0x68737173;
public FileSystemType XmlFsType { get; private set; }
public Encoding Encoding { get; private set; }
public string Name => "Squash filesystem";
public Guid Id => new Guid("F8F6E46F-7A2A-48E3-9C0A-46AF4DC29E09");
public Encoding Encoding { get; private set; }
public string Name => "Squash filesystem";
public Guid Id => new Guid("F8F6E46F-7A2A-48E3-9C0A-46AF4DC29E09");
public bool Identify(IMediaImage imagePlugin, Partition partition)
{
@@ -64,14 +64,14 @@ namespace DiscImageChef.Filesystems
}
public void GetInformation(IMediaImage imagePlugin, Partition partition, out string information,
Encoding encoding)
Encoding encoding)
{
Encoding = encoding ?? Encoding.UTF8;
byte[] sector = imagePlugin.ReadSector(partition.Start);
uint magic = BitConverter.ToUInt32(sector, 0x00);
uint magic = BitConverter.ToUInt32(sector, 0x00);
SquashSuperBlock sqSb = new SquashSuperBlock();
bool littleEndian = true;
SquashSuperBlock sqSb = new SquashSuperBlock();
bool littleEndian = true;
switch(magic)
{
@@ -82,7 +82,7 @@ namespace DiscImageChef.Filesystems
Marshal.FreeHGlobal(sqSbPtr);
break;
case SQUASH_CIGAM:
sqSb = BigEndianMarshal.ByteArrayToStructureBigEndian<SquashSuperBlock>(sector);
sqSb = BigEndianMarshal.ByteArrayToStructureBigEndian<SquashSuperBlock>(sector);
littleEndian = false;
break;
}
@@ -127,15 +127,15 @@ namespace DiscImageChef.Filesystems
XmlFsType = new FileSystemType
{
Type = "Squash file system",
CreationDate = DateHandlers.UnixUnsignedToDateTime(sqSb.mkfs_time),
Type = "Squash file system",
CreationDate = DateHandlers.UnixUnsignedToDateTime(sqSb.mkfs_time),
CreationDateSpecified = true,
Clusters =
(long)((partition.End - partition.Start + 1) * imagePlugin.Info.SectorSize / sqSb.block_size),
ClusterSize = (int)sqSb.block_size,
Files = sqSb.inodes,
FilesSpecified = true,
FreeClusters = 0,
ClusterSize = (int)sqSb.block_size,
Files = sqSb.inodes,
FilesSpecified = true,
FreeClusters = 0,
FreeClustersSpecified = true
};
}
@@ -144,34 +144,34 @@ namespace DiscImageChef.Filesystems
{
Zlib = 1,
Lzma = 2,
Lzo = 3,
Xz = 4,
Lz4 = 5,
Lzo = 3,
Xz = 4,
Lz4 = 5,
Zstd = 6
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct SquashSuperBlock
{
public uint magic;
public uint inodes;
public uint mkfs_time;
public uint block_size;
public uint fragments;
public uint magic;
public uint inodes;
public uint mkfs_time;
public uint block_size;
public uint fragments;
public ushort compression;
public ushort block_log;
public ushort flags;
public ushort no_ids;
public ushort s_major;
public ushort s_minor;
public ulong root_inode;
public ulong bytes_used;
public ulong id_table_start;
public ulong xattr_id_table_start;
public ulong inode_table_start;
public ulong directory_table_start;
public ulong fragment_table_start;
public ulong lookup_table_start;
public ulong root_inode;
public ulong bytes_used;
public ulong id_table_start;
public ulong xattr_id_table_start;
public ulong inode_table_start;
public ulong directory_table_start;
public ulong fragment_table_start;
public ulong lookup_table_start;
}
}
}

View File

@@ -245,9 +245,9 @@ namespace DiscImageChef.Filesystems
[FieldOffset(1)] public bool IsLong;
[FieldOffset(2)] public bool IsGuid;
[FieldOffset(3)] public uint Serial32;
[FieldOffset(3)] public uint Serial32;
[FieldOffset(3)] public ulong Serial64;
[FieldOffset(3)] public Guid uuid;
[FieldOffset(3)] public Guid uuid;
}
/// <summary>

View File

@@ -30,8 +30,6 @@
// Copyright © 2011-2018 Natalia Portillo
// ****************************************************************************/
// Information from http://www.thoukydides.webspace.virginmedia.com/software/psifs/sis.html
// TODO: Implement support for disc images
/*
@@ -360,4 +358,5 @@ namespace DiscImageChef.Plugins
}
}
*/
*/

Some files were not shown because too many files have changed in this diff Show More