mirror of
https://github.com/aaru-dps/Aaru.Server.git
synced 2025-12-16 19:24:27 +00:00
Code cleanup.
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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++)
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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"
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)]
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 /
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -31,7 +31,6 @@
|
||||
// ****************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using DiscImageChef.CommonTypes;
|
||||
using DiscImageChef.DiscImages;
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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]
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -253,7 +253,7 @@ namespace DiscImageChef.Filesystems.LisaFS
|
||||
/// </summary>
|
||||
struct Extent
|
||||
{
|
||||
public int start;
|
||||
public int start;
|
||||
public short length;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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 */
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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)]
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user