mirror of
https://github.com/aaru-dps/Aaru.git
synced 2025-12-16 19:24:25 +00:00
Fix structure naming in Apple filesystems.
This commit is contained in:
@@ -145,7 +145,7 @@ namespace DiscImageChef.Filesystems
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
HfsMasterDirectoryBlock mdb = Marshal.ByteArrayToStructureBigEndian<HfsMasterDirectoryBlock>(mdbSector);
|
MasterDirectoryBlock mdb = Marshal.ByteArrayToStructureBigEndian<MasterDirectoryBlock>(mdbSector);
|
||||||
|
|
||||||
sb.AppendLine("Apple Hierarchical File System");
|
sb.AppendLine("Apple Hierarchical File System");
|
||||||
sb.AppendLine();
|
sb.AppendLine();
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ namespace DiscImageChef.Filesystems
|
|||||||
{
|
{
|
||||||
/// <summary>Master Directory Block, should be sector 2 in volume</summary>
|
/// <summary>Master Directory Block, should be sector 2 in volume</summary>
|
||||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||||
struct HfsMasterDirectoryBlock // Should be sector 2 in volume
|
struct MasterDirectoryBlock // Should be sector 2 in volume
|
||||||
{
|
{
|
||||||
/// <summary>0x000, Signature, 0x4244</summary>
|
/// <summary>0x000, Signature, 0x4244</summary>
|
||||||
public readonly ushort drSigWord;
|
public readonly ushort drSigWord;
|
||||||
|
|||||||
@@ -43,17 +43,11 @@ namespace DiscImageChef.Filesystems
|
|||||||
// Information from Apple TechNote 1150: https://developer.apple.com/legacy/library/technotes/tn/tn1150.html
|
// Information from Apple TechNote 1150: https://developer.apple.com/legacy/library/technotes/tn/tn1150.html
|
||||||
public class AppleHFSPlus : IFilesystem
|
public class AppleHFSPlus : IFilesystem
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>"BD", HFS magic</summary>
|
||||||
/// "BD", HFS magic
|
|
||||||
/// </summary>
|
|
||||||
const ushort HFS_MAGIC = 0x4244;
|
const ushort HFS_MAGIC = 0x4244;
|
||||||
/// <summary>
|
/// <summary>"H+", HFS+ magic</summary>
|
||||||
/// "H+", HFS+ magic
|
|
||||||
/// </summary>
|
|
||||||
const ushort HFSP_MAGIC = 0x482B;
|
const ushort HFSP_MAGIC = 0x482B;
|
||||||
/// <summary>
|
/// <summary>"HX", HFSX magic</summary>
|
||||||
/// "HX", HFSX magic
|
|
||||||
/// </summary>
|
|
||||||
const ushort HFSX_MAGIC = 0x4858;
|
const ushort HFSX_MAGIC = 0x4858;
|
||||||
|
|
||||||
public FileSystemType XmlFsType { get; private set; }
|
public FileSystemType XmlFsType { get; private set; }
|
||||||
@@ -64,12 +58,15 @@ namespace DiscImageChef.Filesystems
|
|||||||
|
|
||||||
public bool Identify(IMediaImage imagePlugin, Partition partition)
|
public bool Identify(IMediaImage imagePlugin, Partition partition)
|
||||||
{
|
{
|
||||||
if(2 + partition.Start >= partition.End) return false;
|
if(2 + partition.Start >= partition.End)
|
||||||
|
return false;
|
||||||
|
|
||||||
ulong hfspOffset;
|
ulong hfspOffset;
|
||||||
|
|
||||||
uint sectorsToRead = 0x800 / imagePlugin.Info.SectorSize;
|
uint sectorsToRead = 0x800 / imagePlugin.Info.SectorSize;
|
||||||
if(0x800 % imagePlugin.Info.SectorSize > 0) sectorsToRead++;
|
|
||||||
|
if(0x800 % imagePlugin.Info.SectorSize > 0)
|
||||||
|
sectorsToRead++;
|
||||||
|
|
||||||
byte[] vhSector = imagePlugin.ReadSectors(partition.Start, sectorsToRead);
|
byte[] vhSector = imagePlugin.ReadSectors(partition.Start, sectorsToRead);
|
||||||
|
|
||||||
@@ -87,15 +84,18 @@ namespace DiscImageChef.Filesystems
|
|||||||
|
|
||||||
ushort drAlBlSt = BigEndianBitConverter.ToUInt16(vhSector, 0x41C);
|
ushort drAlBlSt = BigEndianBitConverter.ToUInt16(vhSector, 0x41C);
|
||||||
|
|
||||||
hfspOffset = (ulong)((drAlBlSt * 512 + xdrStABNt * drAlBlkSiz) / imagePlugin.Info.SectorSize);
|
hfspOffset = (ulong)(((drAlBlSt * 512) + (xdrStABNt * drAlBlkSiz)) / imagePlugin.Info.SectorSize);
|
||||||
}
|
}
|
||||||
else hfspOffset = 0;
|
else
|
||||||
|
hfspOffset = 0;
|
||||||
}
|
}
|
||||||
else hfspOffset = 0;
|
else
|
||||||
|
hfspOffset = 0;
|
||||||
|
|
||||||
vhSector = imagePlugin.ReadSectors(partition.Start + hfspOffset, sectorsToRead); // Read volume header
|
vhSector = imagePlugin.ReadSectors(partition.Start + hfspOffset, sectorsToRead); // Read volume header
|
||||||
|
|
||||||
drSigWord = BigEndianBitConverter.ToUInt16(vhSector, 0x400);
|
drSigWord = BigEndianBitConverter.ToUInt16(vhSector, 0x400);
|
||||||
|
|
||||||
return drSigWord == HFSP_MAGIC || drSigWord == HFSX_MAGIC;
|
return drSigWord == HFSP_MAGIC || drSigWord == HFSX_MAGIC;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,13 +105,15 @@ namespace DiscImageChef.Filesystems
|
|||||||
Encoding = Encoding.BigEndianUnicode;
|
Encoding = Encoding.BigEndianUnicode;
|
||||||
information = "";
|
information = "";
|
||||||
|
|
||||||
HfsPlusVolumeHeader vh = new HfsPlusVolumeHeader();
|
var vh = new VolumeHeader();
|
||||||
|
|
||||||
ulong hfspOffset;
|
ulong hfspOffset;
|
||||||
bool wrapped;
|
bool wrapped;
|
||||||
|
|
||||||
uint sectorsToRead = 0x800 / imagePlugin.Info.SectorSize;
|
uint sectorsToRead = 0x800 / imagePlugin.Info.SectorSize;
|
||||||
if(0x800 % imagePlugin.Info.SectorSize > 0) sectorsToRead++;
|
|
||||||
|
if(0x800 % imagePlugin.Info.SectorSize > 0)
|
||||||
|
sectorsToRead++;
|
||||||
|
|
||||||
byte[] vhSector = imagePlugin.ReadSectors(partition.Start, sectorsToRead);
|
byte[] vhSector = imagePlugin.ReadSectors(partition.Start, sectorsToRead);
|
||||||
|
|
||||||
@@ -129,7 +131,7 @@ namespace DiscImageChef.Filesystems
|
|||||||
|
|
||||||
ushort drAlBlSt = BigEndianBitConverter.ToUInt16(vhSector, 0x41C);
|
ushort drAlBlSt = BigEndianBitConverter.ToUInt16(vhSector, 0x41C);
|
||||||
|
|
||||||
hfspOffset = (ulong)((drAlBlSt * 512 + xdrStABNt * drAlBlkSiz) / imagePlugin.Info.SectorSize);
|
hfspOffset = (ulong)(((drAlBlSt * 512) + (xdrStABNt * drAlBlkSiz)) / imagePlugin.Info.SectorSize);
|
||||||
wrapped = true;
|
wrapped = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -148,45 +150,75 @@ namespace DiscImageChef.Filesystems
|
|||||||
|
|
||||||
vh.signature = BigEndianBitConverter.ToUInt16(vhSector, 0x400);
|
vh.signature = BigEndianBitConverter.ToUInt16(vhSector, 0x400);
|
||||||
|
|
||||||
if(vh.signature != HFSP_MAGIC && vh.signature != HFSX_MAGIC) return;
|
if(vh.signature != HFSP_MAGIC &&
|
||||||
|
vh.signature != HFSX_MAGIC)
|
||||||
|
return;
|
||||||
|
|
||||||
StringBuilder sb = new StringBuilder();
|
var sb = new StringBuilder();
|
||||||
|
|
||||||
if(vh.signature == 0x482B) sb.AppendLine("HFS+ filesystem.");
|
if(vh.signature == 0x482B)
|
||||||
if(vh.signature == 0x4858) sb.AppendLine("HFSX filesystem.");
|
sb.AppendLine("HFS+ filesystem.");
|
||||||
if(wrapped) sb.AppendLine("Volume is wrapped inside an HFS volume.");
|
|
||||||
|
if(vh.signature == 0x4858)
|
||||||
|
sb.AppendLine("HFSX filesystem.");
|
||||||
|
|
||||||
|
if(wrapped)
|
||||||
|
sb.AppendLine("Volume is wrapped inside an HFS volume.");
|
||||||
|
|
||||||
byte[] tmp = new byte[0x400];
|
byte[] tmp = new byte[0x400];
|
||||||
Array.Copy(vhSector, 0x400, tmp, 0, 0x400);
|
Array.Copy(vhSector, 0x400, tmp, 0, 0x400);
|
||||||
vhSector = tmp;
|
vhSector = tmp;
|
||||||
|
|
||||||
vh = Marshal.ByteArrayToStructureBigEndian<HfsPlusVolumeHeader>(vhSector);
|
vh = Marshal.ByteArrayToStructureBigEndian<VolumeHeader>(vhSector);
|
||||||
|
|
||||||
if(vh.version == 4 || vh.version == 5)
|
if(vh.version == 4 ||
|
||||||
|
vh.version == 5)
|
||||||
{
|
{
|
||||||
sb.AppendFormat("Filesystem version is {0}.", vh.version).AppendLine();
|
sb.AppendFormat("Filesystem version is {0}.", vh.version).AppendLine();
|
||||||
|
|
||||||
if((vh.attributes & 0x80) == 0x80) sb.AppendLine("Volume is locked on hardware.");
|
if((vh.attributes & 0x80) == 0x80)
|
||||||
if((vh.attributes & 0x100) == 0x100) sb.AppendLine("Volume is unmounted.");
|
sb.AppendLine("Volume is locked on hardware.");
|
||||||
if((vh.attributes & 0x200) == 0x200) sb.AppendLine("There are bad blocks in the extents file.");
|
|
||||||
if((vh.attributes & 0x400) == 0x400) sb.AppendLine("Volume does not require cache.");
|
if((vh.attributes & 0x100) == 0x100)
|
||||||
if((vh.attributes & 0x800) == 0x800) sb.AppendLine("Volume state is inconsistent.");
|
sb.AppendLine("Volume is unmounted.");
|
||||||
if((vh.attributes & 0x1000) == 0x1000) sb.AppendLine("CNIDs are reused.");
|
|
||||||
if((vh.attributes & 0x2000) == 0x2000) sb.AppendLine("Volume is journaled.");
|
if((vh.attributes & 0x200) == 0x200)
|
||||||
if((vh.attributes & 0x8000) == 0x8000) sb.AppendLine("Volume is locked on software.");
|
sb.AppendLine("There are bad blocks in the extents file.");
|
||||||
|
|
||||||
|
if((vh.attributes & 0x400) == 0x400)
|
||||||
|
sb.AppendLine("Volume does not require cache.");
|
||||||
|
|
||||||
|
if((vh.attributes & 0x800) == 0x800)
|
||||||
|
sb.AppendLine("Volume state is inconsistent.");
|
||||||
|
|
||||||
|
if((vh.attributes & 0x1000) == 0x1000)
|
||||||
|
sb.AppendLine("CNIDs are reused.");
|
||||||
|
|
||||||
|
if((vh.attributes & 0x2000) == 0x2000)
|
||||||
|
sb.AppendLine("Volume is journaled.");
|
||||||
|
|
||||||
|
if((vh.attributes & 0x8000) == 0x8000)
|
||||||
|
sb.AppendLine("Volume is locked on software.");
|
||||||
|
|
||||||
sb.AppendFormat("Implementation that last mounted the volume: \"{0}\".",
|
sb.AppendFormat("Implementation that last mounted the volume: \"{0}\".",
|
||||||
Encoding.ASCII.GetString(vh.lastMountedVersion)).AppendLine();
|
Encoding.ASCII.GetString(vh.lastMountedVersion)).AppendLine();
|
||||||
|
|
||||||
if((vh.attributes & 0x2000) == 0x2000)
|
if((vh.attributes & 0x2000) == 0x2000)
|
||||||
sb.AppendFormat("Journal starts at allocation block {0}.", vh.journalInfoBlock).AppendLine();
|
sb.AppendFormat("Journal starts at allocation block {0}.", vh.journalInfoBlock).AppendLine();
|
||||||
|
|
||||||
sb.AppendFormat("Creation date: {0}", DateHandlers.MacToDateTime(vh.createDate)).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)
|
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");
|
else
|
||||||
|
sb.AppendLine("Volume has never been backed up");
|
||||||
|
|
||||||
if(vh.backupDate > 0)
|
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");
|
else
|
||||||
|
sb.AppendLine("Volume has never been checked up");
|
||||||
|
|
||||||
sb.AppendFormat("{0} files on volume.", vh.fileCount).AppendLine();
|
sb.AppendFormat("{0} files on volume.", vh.fileCount).AppendLine();
|
||||||
sb.AppendFormat("{0} folders on volume.", vh.folderCount).AppendLine();
|
sb.AppendFormat("{0} folders on volume.", vh.folderCount).AppendLine();
|
||||||
sb.AppendFormat("{0} bytes per allocation block.", vh.blockSize).AppendLine();
|
sb.AppendFormat("{0} bytes per allocation block.", vh.blockSize).AppendLine();
|
||||||
@@ -208,10 +240,13 @@ namespace DiscImageChef.Filesystems
|
|||||||
sb.AppendFormat("CNID of previously opened directory: {0}", vh.drFndrInfo2).AppendLine();
|
sb.AppendFormat("CNID of previously opened directory: {0}", vh.drFndrInfo2).AppendLine();
|
||||||
sb.AppendFormat("CNID of bootable Mac OS 8 or 9 directory: {0}", vh.drFndrInfo3).AppendLine();
|
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();
|
sb.AppendFormat("CNID of bootable Mac OS X directory: {0}", vh.drFndrInfo5).AppendLine();
|
||||||
if(vh.drFndrInfo6 != 0 && vh.drFndrInfo7 != 0)
|
|
||||||
|
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();
|
XmlFsType = new FileSystemType();
|
||||||
|
|
||||||
if(vh.backupDate > 0)
|
if(vh.backupDate > 0)
|
||||||
{
|
{
|
||||||
XmlFsType.BackupDate = DateHandlers.MacToDateTime(vh.backupDate);
|
XmlFsType.BackupDate = DateHandlers.MacToDateTime(vh.backupDate);
|
||||||
@@ -221,6 +256,7 @@ namespace DiscImageChef.Filesystems
|
|||||||
XmlFsType.Bootable |= vh.drFndrInfo0 != 0 || vh.drFndrInfo3 != 0 || vh.drFndrInfo5 != 0;
|
XmlFsType.Bootable |= vh.drFndrInfo0 != 0 || vh.drFndrInfo3 != 0 || vh.drFndrInfo5 != 0;
|
||||||
XmlFsType.Clusters = vh.totalBlocks;
|
XmlFsType.Clusters = vh.totalBlocks;
|
||||||
XmlFsType.ClusterSize = vh.blockSize;
|
XmlFsType.ClusterSize = vh.blockSize;
|
||||||
|
|
||||||
if(vh.createDate > 0)
|
if(vh.createDate > 0)
|
||||||
{
|
{
|
||||||
XmlFsType.CreationDate = DateHandlers.MacToDateTime(vh.createDate);
|
XmlFsType.CreationDate = DateHandlers.MacToDateTime(vh.createDate);
|
||||||
@@ -232,16 +268,23 @@ namespace DiscImageChef.Filesystems
|
|||||||
XmlFsType.FilesSpecified = true;
|
XmlFsType.FilesSpecified = true;
|
||||||
XmlFsType.FreeClusters = vh.freeBlocks;
|
XmlFsType.FreeClusters = vh.freeBlocks;
|
||||||
XmlFsType.FreeClustersSpecified = true;
|
XmlFsType.FreeClustersSpecified = true;
|
||||||
|
|
||||||
if(vh.modifyDate > 0)
|
if(vh.modifyDate > 0)
|
||||||
{
|
{
|
||||||
XmlFsType.ModificationDate = DateHandlers.MacToDateTime(vh.modifyDate);
|
XmlFsType.ModificationDate = DateHandlers.MacToDateTime(vh.modifyDate);
|
||||||
XmlFsType.ModificationDateSpecified = true;
|
XmlFsType.ModificationDateSpecified = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(vh.signature == 0x482B) XmlFsType.Type = "HFS+";
|
if(vh.signature == 0x482B)
|
||||||
if(vh.signature == 0x4858) XmlFsType.Type = "HFSX";
|
XmlFsType.Type = "HFS+";
|
||||||
if(vh.drFndrInfo6 != 0 && vh.drFndrInfo7 != 0)
|
|
||||||
|
if(vh.signature == 0x4858)
|
||||||
|
XmlFsType.Type = "HFSX";
|
||||||
|
|
||||||
|
if(vh.drFndrInfo6 != 0 &&
|
||||||
|
vh.drFndrInfo7 != 0)
|
||||||
XmlFsType.VolumeSerial = $"{vh.drFndrInfo6:X8}{vh.drFndrInfo7:X8}";
|
XmlFsType.VolumeSerial = $"{vh.drFndrInfo6:X8}{vh.drFndrInfo7:X8}";
|
||||||
|
|
||||||
XmlFsType.SystemIdentifier = Encoding.ASCII.GetString(vh.lastMountedVersion);
|
XmlFsType.SystemIdentifier = Encoding.ASCII.GetString(vh.lastMountedVersion);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -253,11 +296,9 @@ namespace DiscImageChef.Filesystems
|
|||||||
information = sb.ToString();
|
information = sb.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>HFS+ Volume Header, should be at offset 0x0400 bytes in volume with a size of 532 bytes</summary>
|
||||||
/// HFS+ Volume Header, should be at offset 0x0400 bytes in volume with a size of 532 bytes
|
|
||||||
/// </summary>
|
|
||||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||||
struct HfsPlusVolumeHeader
|
struct VolumeHeader
|
||||||
{
|
{
|
||||||
/// <summary>0x000, "H+" for HFS+, "HX" for HFSX</summary>
|
/// <summary>0x000, "H+" for HFS+, "HX" for HFSX</summary>
|
||||||
public ushort signature;
|
public ushort signature;
|
||||||
@@ -266,12 +307,8 @@ namespace DiscImageChef.Filesystems
|
|||||||
/// <summary>0x004, Volume attributes</summary>
|
/// <summary>0x004, Volume attributes</summary>
|
||||||
public readonly uint attributes;
|
public readonly uint attributes;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 0x008, Implementation that last mounted the volume.
|
/// 0x008, Implementation that last mounted the volume. Reserved by Apple: "8.10" Mac OS 8.1 to 9.2.2 "10.0" Mac
|
||||||
/// Reserved by Apple:
|
/// OS X "HFSJ" Journaled implementation "fsck" /sbin/fsck
|
||||||
/// "8.10" Mac OS 8.1 to 9.2.2
|
|
||||||
/// "10.0" Mac OS X
|
|
||||||
/// "HFSJ" Journaled implementation
|
|
||||||
/// "fsck" /sbin/fsck
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
|
||||||
public readonly byte[] lastMountedVersion;
|
public readonly byte[] lastMountedVersion;
|
||||||
@@ -323,6 +360,7 @@ namespace DiscImageChef.Filesystems
|
|||||||
public readonly uint drFndrInfo6;
|
public readonly uint drFndrInfo6;
|
||||||
/// <summary>0x06C, finderInfo[7], second part of Mac OS X volume ID</summary>
|
/// <summary>0x06C, finderInfo[7], second part of Mac OS X volume ID</summary>
|
||||||
public readonly uint drFndrInfo7;
|
public readonly uint drFndrInfo7;
|
||||||
|
|
||||||
// HFSPlusForkData allocationFile;
|
// HFSPlusForkData allocationFile;
|
||||||
/// <summary>0x070</summary>
|
/// <summary>0x070</summary>
|
||||||
public readonly ulong allocationFile_logicalSize;
|
public readonly ulong allocationFile_logicalSize;
|
||||||
@@ -362,6 +400,7 @@ namespace DiscImageChef.Filesystems
|
|||||||
public readonly uint allocationFile_extents_startBlock7;
|
public readonly uint allocationFile_extents_startBlock7;
|
||||||
/// <summary>0x0BC</summary>
|
/// <summary>0x0BC</summary>
|
||||||
public readonly uint allocationFile_extents_blockCount7;
|
public readonly uint allocationFile_extents_blockCount7;
|
||||||
|
|
||||||
// HFSPlusForkData extentsFile;
|
// HFSPlusForkData extentsFile;
|
||||||
/// <summary>0x0C0</summary>
|
/// <summary>0x0C0</summary>
|
||||||
public readonly ulong extentsFile_logicalSize;
|
public readonly ulong extentsFile_logicalSize;
|
||||||
@@ -401,6 +440,7 @@ namespace DiscImageChef.Filesystems
|
|||||||
public readonly uint extentsFile_extents_startBlock7;
|
public readonly uint extentsFile_extents_startBlock7;
|
||||||
/// <summary>0x10C</summary>
|
/// <summary>0x10C</summary>
|
||||||
public readonly uint extentsFile_extents_blockCount7;
|
public readonly uint extentsFile_extents_blockCount7;
|
||||||
|
|
||||||
// HFSPlusForkData catalogFile;
|
// HFSPlusForkData catalogFile;
|
||||||
/// <summary>0x110</summary>
|
/// <summary>0x110</summary>
|
||||||
public readonly ulong catalogFile_logicalSize;
|
public readonly ulong catalogFile_logicalSize;
|
||||||
@@ -440,6 +480,7 @@ namespace DiscImageChef.Filesystems
|
|||||||
public readonly uint catalogFile_extents_startBlock7;
|
public readonly uint catalogFile_extents_startBlock7;
|
||||||
/// <summary>0x15C</summary>
|
/// <summary>0x15C</summary>
|
||||||
public readonly uint catalogFile_extents_blockCount7;
|
public readonly uint catalogFile_extents_blockCount7;
|
||||||
|
|
||||||
// HFSPlusForkData attributesFile;
|
// HFSPlusForkData attributesFile;
|
||||||
/// <summary>0x160</summary>
|
/// <summary>0x160</summary>
|
||||||
public readonly ulong attributesFile_logicalSize;
|
public readonly ulong attributesFile_logicalSize;
|
||||||
@@ -479,6 +520,7 @@ namespace DiscImageChef.Filesystems
|
|||||||
public readonly uint attributesFile_extents_startBlock7;
|
public readonly uint attributesFile_extents_startBlock7;
|
||||||
/// <summary>0x1AC</summary>
|
/// <summary>0x1AC</summary>
|
||||||
public readonly uint attributesFile_extents_blockCount7;
|
public readonly uint attributesFile_extents_blockCount7;
|
||||||
|
|
||||||
// HFSPlusForkData startupFile;
|
// HFSPlusForkData startupFile;
|
||||||
/// <summary>0x1B0</summary>
|
/// <summary>0x1B0</summary>
|
||||||
public readonly ulong startupFile_logicalSize;
|
public readonly ulong startupFile_logicalSize;
|
||||||
|
|||||||
@@ -45,12 +45,10 @@ namespace DiscImageChef.Filesystems.AppleMFS
|
|||||||
bool debug;
|
bool debug;
|
||||||
IMediaImage device;
|
IMediaImage device;
|
||||||
ulong partitionStart;
|
ulong partitionStart;
|
||||||
|
|
||||||
Dictionary<uint, string> idToFilename;
|
Dictionary<uint, string> idToFilename;
|
||||||
Dictionary<uint, MFS_FileEntry> idToEntry;
|
Dictionary<uint, FileEntry> idToEntry;
|
||||||
Dictionary<string, uint> filenameToId;
|
Dictionary<string, uint> filenameToId;
|
||||||
|
MasterDirectoryBlock volMDB;
|
||||||
MFS_MasterDirectoryBlock volMDB;
|
|
||||||
byte[] bootBlocks;
|
byte[] bootBlocks;
|
||||||
byte[] mdbBlocks;
|
byte[] mdbBlocks;
|
||||||
byte[] directoryBlocks;
|
byte[] directoryBlocks;
|
||||||
@@ -70,11 +68,16 @@ namespace DiscImageChef.Filesystems.AppleMFS
|
|||||||
|
|
||||||
// TODO: Implement Finder namespace (requires decoding Desktop database)
|
// TODO: Implement Finder namespace (requires decoding Desktop database)
|
||||||
public IEnumerable<(string name, Type type, string description)> SupportedOptions =>
|
public IEnumerable<(string name, Type type, string description)> SupportedOptions =>
|
||||||
new (string name, Type type, string description)[] { };
|
new (string name, Type type, string description)[]
|
||||||
|
{ };
|
||||||
|
|
||||||
public Dictionary<string, string> Namespaces => null;
|
public Dictionary<string, string> Namespaces => null;
|
||||||
|
|
||||||
static Dictionary<string, string> GetDefaultOptions() =>
|
static Dictionary<string, string> GetDefaultOptions() => new Dictionary<string, string>
|
||||||
new Dictionary<string, string> {{"debug", false.ToString()}};
|
{
|
||||||
|
{
|
||||||
|
"debug", false.ToString()
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -73,19 +73,19 @@ namespace DiscImageChef.Filesystems.AppleMFS
|
|||||||
bool FillDirectory()
|
bool FillDirectory()
|
||||||
{
|
{
|
||||||
idToFilename = new Dictionary<uint, string>();
|
idToFilename = new Dictionary<uint, string>();
|
||||||
idToEntry = new Dictionary<uint, MFS_FileEntry>();
|
idToEntry = new Dictionary<uint, FileEntry>();
|
||||||
filenameToId = new Dictionary<string, uint>();
|
filenameToId = new Dictionary<string, uint>();
|
||||||
|
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
|
|
||||||
while(offset + 51 < directoryBlocks.Length)
|
while(offset + 51 < directoryBlocks.Length)
|
||||||
{
|
{
|
||||||
var entry = new MFS_FileEntry
|
var entry = new FileEntry
|
||||||
{
|
{
|
||||||
flFlags = (MFS_FileFlags)directoryBlocks[offset + 0]
|
flFlags = (FileFlags)directoryBlocks[offset + 0]
|
||||||
};
|
};
|
||||||
|
|
||||||
if(!entry.flFlags.HasFlag(MFS_FileFlags.Used))
|
if(!entry.flFlags.HasFlag(FileFlags.Used))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
entry.flTyp = directoryBlocks[offset + 1];
|
entry.flTyp = directoryBlocks[offset + 1];
|
||||||
@@ -108,7 +108,7 @@ namespace DiscImageChef.Filesystems.AppleMFS
|
|||||||
string lowerFilename = StringHandlers.
|
string lowerFilename = StringHandlers.
|
||||||
PascalToString(entry.flNam, Encoding).ToLowerInvariant().Replace('/', ':');
|
PascalToString(entry.flNam, Encoding).ToLowerInvariant().Replace('/', ':');
|
||||||
|
|
||||||
if(entry.flFlags.HasFlag(MFS_FileFlags.Used) &&
|
if(entry.flFlags.HasFlag(FileFlags.Used) &&
|
||||||
!idToFilename.ContainsKey(entry.flFlNum) &&
|
!idToFilename.ContainsKey(entry.flFlNum) &&
|
||||||
!idToEntry.ContainsKey(entry.flFlNum) &&
|
!idToEntry.ContainsKey(entry.flFlNum) &&
|
||||||
!filenameToId.ContainsKey(lowerFilename) &&
|
!filenameToId.ContainsKey(lowerFilename) &&
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ namespace DiscImageChef.Filesystems.AppleMFS
|
|||||||
if(!filenameToId.TryGetValue(path.ToLowerInvariant(), out uint fileId))
|
if(!filenameToId.TryGetValue(path.ToLowerInvariant(), out uint fileId))
|
||||||
return Errno.NoSuchFile;
|
return Errno.NoSuchFile;
|
||||||
|
|
||||||
if(!idToEntry.TryGetValue(fileId, out MFS_FileEntry entry))
|
if(!idToEntry.TryGetValue(fileId, out FileEntry entry))
|
||||||
return Errno.NoSuchFile;
|
return Errno.NoSuchFile;
|
||||||
|
|
||||||
if(fileBlock > entry.flPyLen / volMDB.drAlBlkSiz)
|
if(fileBlock > entry.flPyLen / volMDB.drAlBlkSiz)
|
||||||
@@ -111,7 +111,7 @@ namespace DiscImageChef.Filesystems.AppleMFS
|
|||||||
if(!filenameToId.TryGetValue(path.ToLowerInvariant(), out uint fileId))
|
if(!filenameToId.TryGetValue(path.ToLowerInvariant(), out uint fileId))
|
||||||
return Errno.NoSuchFile;
|
return Errno.NoSuchFile;
|
||||||
|
|
||||||
if(!idToEntry.TryGetValue(fileId, out MFS_FileEntry entry))
|
if(!idToEntry.TryGetValue(fileId, out FileEntry entry))
|
||||||
return Errno.NoSuchFile;
|
return Errno.NoSuchFile;
|
||||||
|
|
||||||
if(entry.flUsrWds.fdFlags.HasFlag(AppleCommon.FinderFlags.kIsAlias))
|
if(entry.flUsrWds.fdFlags.HasFlag(AppleCommon.FinderFlags.kIsAlias))
|
||||||
@@ -132,7 +132,7 @@ namespace DiscImageChef.Filesystems.AppleMFS
|
|||||||
if(entry.flUsrWds.fdFlags.HasFlag(AppleCommon.FinderFlags.kIsInvisible))
|
if(entry.flUsrWds.fdFlags.HasFlag(AppleCommon.FinderFlags.kIsInvisible))
|
||||||
attributes |= FileAttributes.Hidden;
|
attributes |= FileAttributes.Hidden;
|
||||||
|
|
||||||
if(entry.flFlags.HasFlag(MFS_FileFlags.Locked))
|
if(entry.flFlags.HasFlag(FileFlags.Locked))
|
||||||
attributes |= FileAttributes.Immutable;
|
attributes |= FileAttributes.Immutable;
|
||||||
|
|
||||||
if(entry.flUsrWds.fdFlags.HasFlag(AppleCommon.FinderFlags.kIsOnDesk))
|
if(entry.flUsrWds.fdFlags.HasFlag(AppleCommon.FinderFlags.kIsOnDesk))
|
||||||
@@ -258,7 +258,7 @@ namespace DiscImageChef.Filesystems.AppleMFS
|
|||||||
if(!filenameToId.TryGetValue(path.ToLowerInvariant(), out uint fileId))
|
if(!filenameToId.TryGetValue(path.ToLowerInvariant(), out uint fileId))
|
||||||
return Errno.NoSuchFile;
|
return Errno.NoSuchFile;
|
||||||
|
|
||||||
if(!idToEntry.TryGetValue(fileId, out MFS_FileEntry entry))
|
if(!idToEntry.TryGetValue(fileId, out FileEntry entry))
|
||||||
return Errno.NoSuchFile;
|
return Errno.NoSuchFile;
|
||||||
|
|
||||||
Errno error = GetAttributes(path, out FileAttributes attr);
|
Errno error = GetAttributes(path, out FileAttributes attr);
|
||||||
@@ -304,7 +304,7 @@ namespace DiscImageChef.Filesystems.AppleMFS
|
|||||||
if(!filenameToId.TryGetValue(path.ToLowerInvariant(), out uint fileId))
|
if(!filenameToId.TryGetValue(path.ToLowerInvariant(), out uint fileId))
|
||||||
return Errno.NoSuchFile;
|
return Errno.NoSuchFile;
|
||||||
|
|
||||||
if(!idToEntry.TryGetValue(fileId, out MFS_FileEntry entry))
|
if(!idToEntry.TryGetValue(fileId, out FileEntry entry))
|
||||||
return Errno.NoSuchFile;
|
return Errno.NoSuchFile;
|
||||||
|
|
||||||
uint nextBlock;
|
uint nextBlock;
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ namespace DiscImageChef.Filesystems.AppleMFS
|
|||||||
|
|
||||||
var sb = new StringBuilder();
|
var sb = new StringBuilder();
|
||||||
|
|
||||||
var mdb = new MFS_MasterDirectoryBlock();
|
var mdb = new MasterDirectoryBlock();
|
||||||
|
|
||||||
byte[] pString = new byte[16];
|
byte[] pString = new byte[16];
|
||||||
|
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ namespace DiscImageChef.Filesystems.AppleMFS
|
|||||||
public partial class AppleMFS
|
public partial class AppleMFS
|
||||||
{
|
{
|
||||||
/// <summary>Master Directory Block, should be at offset 0x0400 bytes in volume</summary>
|
/// <summary>Master Directory Block, should be at offset 0x0400 bytes in volume</summary>
|
||||||
struct MFS_MasterDirectoryBlock
|
struct MasterDirectoryBlock
|
||||||
{
|
{
|
||||||
/// <summary>0x000, Signature, 0xD2D7</summary>
|
/// <summary>0x000, Signature, 0xD2D7</summary>
|
||||||
public ushort drSigWord;
|
public ushort drSigWord;
|
||||||
@@ -77,15 +77,15 @@ namespace DiscImageChef.Filesystems.AppleMFS
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Flags]
|
[Flags]
|
||||||
enum MFS_FileFlags : byte
|
enum FileFlags : byte
|
||||||
{
|
{
|
||||||
Locked = 0x01, Used = 0x80
|
Locked = 0x01, Used = 0x80
|
||||||
}
|
}
|
||||||
|
|
||||||
struct MFS_FileEntry
|
struct FileEntry
|
||||||
{
|
{
|
||||||
/// <summary>0x00, Entry flags</summary>
|
/// <summary>0x00, Entry flags</summary>
|
||||||
public MFS_FileFlags flFlags;
|
public FileFlags flFlags;
|
||||||
/// <summary>0x01, Version number</summary>
|
/// <summary>0x01, Version number</summary>
|
||||||
public byte flTyp;
|
public byte flTyp;
|
||||||
/// <summary>0x02, FinderInfo</summary>
|
/// <summary>0x02, FinderInfo</summary>
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ namespace DiscImageChef.Filesystems.AppleMFS
|
|||||||
if(options.TryGetValue("debug", out string debugString))
|
if(options.TryGetValue("debug", out string debugString))
|
||||||
bool.TryParse(debugString, out debug);
|
bool.TryParse(debugString, out debug);
|
||||||
|
|
||||||
volMDB = new MFS_MasterDirectoryBlock();
|
volMDB = new MasterDirectoryBlock();
|
||||||
|
|
||||||
mdbBlocks = device.ReadSector(2 + partitionStart);
|
mdbBlocks = device.ReadSector(2 + partitionStart);
|
||||||
bootBlocks = device.ReadSector(0 + partitionStart);
|
bootBlocks = device.ReadSector(0 + partitionStart);
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ namespace DiscImageChef.Filesystems.AppleMFS
|
|||||||
if(!filenameToId.TryGetValue(path.ToLowerInvariant(), out uint fileId))
|
if(!filenameToId.TryGetValue(path.ToLowerInvariant(), out uint fileId))
|
||||||
return Errno.NoSuchFile;
|
return Errno.NoSuchFile;
|
||||||
|
|
||||||
if(!idToEntry.TryGetValue(fileId, out MFS_FileEntry entry))
|
if(!idToEntry.TryGetValue(fileId, out FileEntry entry))
|
||||||
return Errno.NoSuchFile;
|
return Errno.NoSuchFile;
|
||||||
|
|
||||||
if(entry.flRLgLen > 0)
|
if(entry.flRLgLen > 0)
|
||||||
@@ -162,7 +162,7 @@ namespace DiscImageChef.Filesystems.AppleMFS
|
|||||||
if(!filenameToId.TryGetValue(path.ToLowerInvariant(), out uint fileId))
|
if(!filenameToId.TryGetValue(path.ToLowerInvariant(), out uint fileId))
|
||||||
return Errno.NoSuchFile;
|
return Errno.NoSuchFile;
|
||||||
|
|
||||||
if(!idToEntry.TryGetValue(fileId, out MFS_FileEntry entry))
|
if(!idToEntry.TryGetValue(fileId, out FileEntry entry))
|
||||||
return Errno.NoSuchFile;
|
return Errno.NoSuchFile;
|
||||||
|
|
||||||
if(entry.flRLgLen > 0 &&
|
if(entry.flRLgLen > 0 &&
|
||||||
|
|||||||
Reference in New Issue
Block a user